从文件中获取可变子字符串长度的最快方法 (C#)

Fastest way to get variable substring lengths from file (C#)

我有一个文本文件,其中包含需要提取的值,每个值的长度都是可变的。每个变量的长度存储在List<int>中,如果有更有效的方法,可以更改。

问题:给定 List<int> 长度,将可变长度子字符串放入 DataTable 的最快方法是什么?

示例文本文件内容:

Field1ValueField2ValueIsLongerField3Field4IsExtremelyLongField5IsProbablyTheLongestFieldOfThemAll
A1201605172B160349150816431572C16584D31601346427946121346E674306102966595346438476174959205395664

示例List<int>

11, 19, 6, 21, 40

示例输出 DataTable:

Field 1 Field 2 Field 3 Field 4 Field 5
Field1Value Field2ValueIsLonger Field3 Field4IsExtremelyLong Field5IsProbablyTheLongestFieldOfThemAll
A1201605172 B160349150816431572 C16584 D31601346427946121346 E674306102966595346438476174959205395664

字段值没有模式,可以是任何字母数字值,并且只能通过长度列表获取字段值。

我的方法如下:

List<int> lengths = new() { 11, 19, 6, 21, 40};

DataTable dataTable = new();

//Add Columns for each field
foreach (int i in lengths)
{
    dataTable.Columns.Add();
}

//Read file and get fields
using (StreamReader streamReader = new(fileName))
{
    string line; //temp
    while ((line = streamReader.ReadLine()) != null)
    {
        //Create new row each time we see a new line in the text file
        DataRow dataRow = dataTable.NewRow();

        //Temp counter for starting index of substring
        int tempCounter = 0;

        //Enumerate through variable lengths
        foreach (int i in lengths)
        {
            //Set the value for tat cell
            dataRow[lengths.IndexOf(i)] = line.Substring(tempCounter, i);

            //Add the length of the current field
            tempCounter += i;
        }

        //Add Row to DataTable
        dataTable.Rows.Add(dataRow);
    }
}

是否有更高效(时间 and/or 记忆)的方式来完成这个任务?

你是在生成那个输入字符串还是那个长度数组?

如果是:

  • 保存每个第N个字段起始字符的索引(如果你已经有length-array,那么你也可以建立一个start-array)
  • 然后在解码时,使用多个线程一次解析多个索引点并将它们连接到目标列表或数组(imo 数组必须更快,因为你有总数的字段)

如果没有:

  • 将遇到的每个字段开始推入队列(带有字段索引)并直接跳转到下一个字段
  • 由其他线程从队列中异步弹出元素,并根据它们的索引将它们放入列表中(如果知道总长度,数组可能会更好)

因为当您在同一个循环中同时进行提取和解析时,提取吞吐量会下降。因此,您应该将工作卸载到其他线程,也许一次使用 N 个字段以容忍 multi-threading 同步延迟。

如果 single-thread 提取比 multi-thread 解析太慢,那么您可以尝试矢量化提取。一次启动 128 个字符采样器,检查它们是否找到前缀代码并在它们之间进行归约以找到其中的第一个前缀(如果找到多个)。