我目前正在开发一个读取大约50000行文本文件的应用程序。对于每一行,我需要检查它是否包含特定的字符串。
目前,我使用传统的System.IO.StreamReader
逐行读取我的文件。
问题是文本文件的大小每次都会改变。我做了几个测试性能,我注意到当文件大小增加时,读取一行所需的时间就越多。
读取包含5000行的txt文件:0:40
读取包含10000行的txt文件:2:54
读取2倍大的文件需要4倍的时间。我无法想象读取100000行文件需要多长时间。
这是我的代码:
using (StreamReader streamReader = new StreamReader(this.MyPath))
{
while (streamReader.Peek() > 0)
{
string line = streamReader.ReadLine();
if (line.Contains(Resources.Constants.SpecificString)
{
// Do some action with the string.
}
}
}
有没有办法避免这种情况:更大的文件=更多时间阅读一行?
答案 0 :(得分:5)
试试这个:
var toSearch = Resources.Constants.SpecificString;
foreach (var str in File.ReadLines(MyPath).Where(s => s.Contains(toSearch))) {
// Do some action with the string
}
这可以避免在循环之前通过缓存值来访问每次迭代的资源。如果这没有用,请尝试根据高级字符串搜索算法编写自己的Contains
,例如KMP。
注意:请务必使用File.ReadLines懒惰地读取行(与同时读取所有行的类似File.ReadAllLines
不同)。
答案 1 :(得分:0)
使用RegEx.IsMatch
,您会看到一些性能改进。
using (StreamReader streamReader = new StreamReader(this.MyPath))
{
var regEx = new RegEx(MyPattern, RegexOptions.Compiled);
while (streamReader.Peek() > 0)
{
string line = streamReader.ReadLine();
if (regEx.IsMatch(line))
{
// Do some action with the string.
}
}
}
但请记住使用已编译的RegEx。这是一个pretty good article,你可以看一些基准。
快乐的编码!