我正在开发一个 C# 程序,该程序读取非常大的文件并检查它们的不同属性和字段。我一直在测试少于 100 万行的文件,它按预期执行。我最近在一个 250 万行的文件上进行了测试,花了 4 个小时才跑完。
我正在使用自定义阅读功能来读取每个字符,以便我可以找到所有 CR 和 LF,因为每一行都包含它们非常重要。我单独测试了阅读功能,阅读文件大约需要 14 分钟,我认为这足以阅读 250 万行 1500 个字符中的每个字符。我将包括我的阅读功能,但这似乎不是导致问题的原因。
我的阅读函数将每个字符添加到一个字符串中,然后检查字符串中的不同值。例如,行长度是否正确,文件是否包含标题,以及标题是否包含正确的值。以及特定值,例如字符位置 403-404 是一个数字,字段 1250-1300 是否不为空等。
我的问题是,我可以做些什么来找出导致程序变慢并提高程序效率的原因?我试过检查每行循环开始和结束的时间,它似乎没有改变。但是,每 100,000 个花费的时间明显比前一个长。例如,处理 10,000 到 20,000 行用了不到 3 秒,而 830,000 到 840,000 行用了大约 35 秒。我考虑过尝试使用多个线程,但我认为这对我从文件中读取行没有帮助。想法?谢谢您的帮助!
static void ReadMyLine(ref string currentLine, string filePath, ref int asciiValue, ref Boolean isMissingCR, ref Boolean isMissingLF, ref Boolean isReversed, ref StreamReader file)
{
Boolean endOfRow = false;
isMissingCR = false;
isMissingLF = false;
isReversed = false;
currentLine = "";
while (endOfRow == false)
{
asciiValue = file.Read();
if (asciiValue == 10 || asciiValue == 13)
{
int asciiValueTemp = file.Peek();
if (asciiValue == 13 && asciiValueTemp == 10)
{
endOfRow = true;
asciiValue = file.Read();
}
else if (asciiValue == 10 && asciiValueTemp == 13) // CRLF Reversed
{
asciiValue = file.Read();
endOfRow = true;
isReversed = true;
}
else if (asciiValue == 10) // Missing CR
{
isMissingCR = true;
endOfRow = true;
}
else if (asciiValue == 13) // Missing LF
{
isMissingLF = true;
endOfRow = true;
}
else
endOfRow = true;
}
else if (asciiValue != -1)
currentLine += char.ConvertFromUtf32(asciiValue);
else
endOfRow = true;
}
}
最佳答案
这是我寻找的第一个东西,也是我要更改的第一个东西:
currentLine += char.ConvertFromUtf32(asciiValue);
不要那样做。在循环中使用字符串连接会杀死 性能 - 您会得到 O(N2) 的复杂度。请改用 StringBuilder
。参见 my article on when to use StringBuilder
以获得更多解释。
您可以做的事情可能更多,但只需更改为使用 StringBuilder
就会巨大改进:
StringBuilder builder = new StringBuilder();
while (...)
{
...
builder.Append(char.ConvertFromUtf32(asciiValue));
}
currentLine = builder.ToString();
也不清楚为什么你有这么多 ref 参数。你为什么要传入 asciiValue
?为什么要通过引用传递 StreamReader
?任何使用这么多 ref 参数的东西都让我非常紧张 - 为什么你没有一个类型来封装你真正想要从方法返回的所有内容?
您可能想阅读我的 article on parameter passing更好地理解 ref
。
关于C# 提高程序效率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7362987/