string.Split()与C#中的string.Substring()的效率?

时间:2014-07-16 15:25:39

标签: c# string performance split substring

我正在处理涉及获取大型文本文件并解析每一行的项目。关键是将整个文本文件解析为单元格,就像Excel电子表格一样。不幸的是,大多数文件都没有分隔符,所以我需要某种基于索引的方法来手动创建单元格,即使列是空白的。

以前,通过拆分null来解析行,这很有效。然而,新数据使得这种方法不可靠,因为它不包括空白单元格,所以我不得不创建一种解析行的新方法,它使用Substring。该方法接受一个整数索引数组并拆分给定索引上的字符串:

private string[] SetCols3(int[] fixedWidthValues, string line)
{
    {
    string[] cols = new string[fixedWidthValues.Length];

    int columnLength;
    int FWV;
    int FWV2;

    bool lastOfFWV;
    bool outOfBounds;

    for (int x = 0; x < fixedWidthValues.Length; x++)
    {
        FWV = fixedWidthValues[x];
        lastOfFWV = x + 1 >= fixedWidthValues.Length;
        outOfBounds = lastOfFWV ? true : fixedWidthValues[x + 1] >= line.Length;
        FWV2 = lastOfFWV || outOfBounds ? line.Length : fixedWidthValues[x + 1];
        columnLength = FWV2 - FWV;
        columnLength *= columnLength < 0 ? -1 : 1;

        if (FWV < line.Length)
        {
            cols[x] = line.Substring(FWV, columnLength).Trim();
        }
    }

    return cols;
}

代码的快速细分:整数和布尔值只是处理空白列,比正常情况更短的行等,并使代码更清晰,以便其他人更好地理解(而不是一个长) ,如果声明错综复杂。

我的问题:有没有办法提高效率?由于某种原因,此方法比以前的方法花费更长的时间。我知道它做得更多,所以预计会有更多的时间。然而,差异是惊人的巨大。一次迭代(15个索引)大约需要0.07秒(考虑到这个方法每个文件被调用几千次,这是巨大的),相比之下,对于分割为null的方法,高端为0.00002秒。我可以在代码中更改某些内容以显着提高效率吗?经过数小时在线搜索后,我找不到任何特别有用的东西。

此外,索引/列的数量会极大地影响速度。对于15列,它需要大约0.07秒,而10列需要0.05。

2 个答案:

答案 0 :(得分:0)

首先,

outOfBounds = lastOfFWV ? true : fixedWidthValues[x + 1] >= line.Length;

可以更改为

outOfBounds = lastOfFWV || fixedWidthValues[x + 1] >= line.Length;

接下来,

columnLength = FWV2 - FWV;
columnLength *= columnLength < 0 ? -1 : 1;

可以更改为

columnLength = Math.Abs(FWV2 - FWV);

最后,

if (FWV < line.Length)
{

可以移动到循环顶部的FWV赋值之后并更改为

if (FWV < line.Length)
    continue;

但是,我不认为这些变化会对速度产生重大影响。通过改变传入的内容可能会获得更大的影响。不是传入列起始位置并计算每行不会发生变化的列宽,而是传递起始位置和列宽。这样就不会涉及计算。

但不是猜测,最好是找出找到热点的方法。

答案 1 :(得分:0)

问题是两个流浪.ToInt32()调用我不小心包括(我不知道他们为什么在那里)。这个特殊方法与我公司的方法不同,而不是Convert.ToInt32(),并且由于某种原因,在尝试转换数字时效率非常低。作为参考,问题如下:

FWV = fixedWidthValues[x].ToInt32();
...
FWV2 = lastOfFWV || outOfBounds ? line.Length : fixedWidthValues[x + 1].ToInt32();

移除它们可将效率提高60倍......