C#:在处理大型txt文件中的字符串时性能较差
本文关键字:字符串 性能 文件 处理 大型 txt | 更新日期: 2023-09-27 18:25:53
我有一个大的txt文件,我必须在其中找到一些记录并将它们重写到其他文件。
我的方法是这样的:
private ArrayList getRelatingObjects(string[] Ob, string Tab)
{
ArrayList rel = new ArrayList();
foreach (string[] s in SO)
{
foreach (string x in s)
{
if (x.Length > 0)
{
if (x[0].Equals('W'))
{
string xTemp = x.Substring(x.IndexOf(',') + 1);
xTemp = xTemp.Substring(xTemp.IndexOf(',') + 1);
xTemp = xTemp.Substring(xTemp.IndexOf(',') + 1).Replace(";", "");
string obTemp = Ob[0].Substring(Ob[0].IndexOf(',', 3) + 1);
obTemp = obTemp.Substring(obTemp.IndexOf(',') + 1);
obTemp = obTemp.Substring(0, obTemp.IndexOf(','));
if (xTemp.Equals(obTemp) && (x.Substring(x.IndexOf(',', 3) + 1).Contains(Tab)))
{
if (!rel.Contains(s) && !s[0].Substring(x.IndexOf(',', 3) + 1).Contains("G5ZMN"))
{
rel.Add(s);
}
}
}
}
}
}
return rel;
}
SO是ArrayList,我把记录的数组放在这里(有一些类似于DB中的数组)。在这里,我需要找到与我选择的对象相关的对象。
问题是,当我使用2MB这样的文件时,速度不够快。(我已经用Substrings替换了Splits函数(它们比我检查的移除更快)。
但我的表现还不够。
你知道我怎样才能做得更快吗?我在SubStrings和replace上损失了大部分CPU功率,但我仍然不知道是否能更快地完成。
这不是一个100%的解决方案,因为你我没有确切描述你想要接收的元素
private IEnumerable<string> ReadData(string filepath)
{
var res = new List<string>( );
var fileInfo = new FileInfo( filepath );
if( !fileInfo.Exists )
{
throw new ArgumentException( "No file exist with the path " + filepath,
"filepath" );
}
var fileStream = fileInfo.Open( FileMode.Open,
FileAccess.Read );
var file = new StreamReader( fileStream,
Encoding.UTF8 );
string lineOfText;
while( ( lineOfText = file.ReadLine( ) ) != null )
{
var pattern = new Regex( @"^['w]{2},['w]{0,},['w]{1,},(['w]{1,})(?:,['w]{0,},['w]{1,}){0,1};$");
var match = pattern.Match( lineOfText );
if( match.Success )
{
res.Add( match.Groups[ 0 ].Value );
}
else
{
// Handle lines with wrong format
}
}
return res;
}
解释模式:
^(锚定到字符串的开头)
"''w"中的任何字符
正好2次
,
"''w"中的任何字符
至少0次
,
"''w"中的任何字符
至少1次
,
捕获=>结果的元素
"''w"中的任何字符
至少1次
结束捕获
非捕获组
,
"''w"中的任何字符
至少0次
,
"''w"中的任何字符
至少1次
结束捕获
至少0次,但不超过1次
;$(锚定到字符串末尾)
首先,字符串在C#中是不可变的。每次调用子字符串或replace方法时,都会创建一个新的字符串。请尝试使用StringBuilder。
其次,如果要将一大块字符串直接加载到内存中,可以考虑使用类似StreamReader类的东西
最后,您可能应该使用Regex进行模式匹配。