C# 加速解析算法
我正在解析一些ddump文件,你能帮我加快算法吗?C# 加速解析算法,c#,algorithm,parsing,refactoring,C#,Algorithm,Parsing,Refactoring,我正在解析一些ddump文件,你能帮我加快算法吗? 每个循环需要216毫秒!!这太过分了。我想让它大约40-50毫秒每循环。也许通过使用RegExp 这是我的忠告: 任何帮助都将不胜感激。好吧,请多次这样做 EntireFile.ToLower() 当然不会有帮助。您可以做以下几件事: 仅执行一次代价高昂的操作(ToLower,IndexOf等),并尽可能缓存结果 不要缩小使用子字符串处理的输入范围,这会降低性能。相反,保留一个单独的intparsestart值,并将其用作所有IndexO
每个循环需要216毫秒!!这太过分了。我想让它大约40-50毫秒每循环。也许通过使用RegExp 这是我的忠告:
任何帮助都将不胜感激。好吧,请多次这样做
EntireFile.ToLower()
当然不会有帮助。您可以做以下几件事:
ToLower
,IndexOf
等),并尽可能缓存结果子字符串处理的输入范围,这会降低性能。相反,保留一个单独的intparsestart
值,并将其用作所有IndexOf
调用的附加参数。换句话说,跟踪手动解析的文件部分,而不是每次都使用较小的子字符串
性能问题主要与所有字符串复制操作的开销有关 如果通过简单地使用索引对整个字符串进行虚拟子串来消除复制,则可以使用重载来指定字符串操作的有效范围,这将产生影响 此外,不区分大小写的比较不是通过降低或提高字符串来实现的!您可以使用
StringComparer
类或StringComparsion
枚举。有许多字符串重载让您指定是否考虑大小写敏感度。
重复使用方括号表示法为字符串编制索引也是非常昂贵的。如果您查看.NET中字符串操作的实现,它们总是将搜索字符串转换为字符数组,因为这样处理起来更快。然而,这意味着即使对于只读搜索操作,也会有大量的复制发生。我建议使用分析工具来关注代码中减慢速度的部分
JetBrains dotTrace是一款分析产品,它对这类任务有着巨大的帮助。据我所知,除了Jon的答案之外,代码的while()部分中的任何内容都将在每个循环中执行。因此,找到一种不重新计算的方法可能会更快
EntireFile.Substring(pos, EntireFile.Length - pos)).Contains(" class")
在while循环的每次迭代中。另外,您到底想解析什么?它是普通的文本文件吗?你没有给出很多细节。我喜欢用来解析文本文件的一种方法是使用“\n”作为分隔符将整个文件加载到字符串数组中。然后我可以快速遍历数组并解析内容。如果需要,我可以存储数组索引并快速引用前一行。首先,您可以更改
while (pos < EntireFile.Length && (/*curr = */EntireFile.Substring(pos, EntireFile.Length - pos)).Contains(" class"))
{
...
}
到
正如其他人所建议的那样
var loweredEntiredFile = EntiredFile.ToLower();
应该在一段时间之外完成一次,并且
loweredEntireFile = loweredEntireFile.Substring(pos, loweredEntireFile.Length - pos));
需要在while结束时完成我很想知道转储文件的格式。文件大小是多少?是否有您可以共享的数据示例?将“EntireFile.ToLower()”移出循环将是一个合理的开始,但您可能应该询问探查器,它在哪里影响最大。如果你证明了样本数据和一个完整的工作程序,可能有人会有时间来使用它。这是一个Nemo 440转储文件,但我本来不想发布它,因为它可能会产生一个关于反编译的道德讨论…使用regexp、IndexOf、Substring和类似的东西根本不算是“解析”。为什么不使用一些更传统的解析方法呢?至少是递归下降解析?我怀疑OP真正需要的是一个快速的lexer。他的大部分时间都花在挑选字符串上,这是lexers做得非常好、速度非常快的地方。再加上……将该方法的结果放入变量中并重用它。否则,你就要处理整个文件,并且每次调用它时都必须将所有内容处理为小写。@alex:当然,如果你需要子字符串作为结果,那么就使用子字符串。只是不要将它们用于中间处理。字符串操作非常昂贵。像您建议的那样缓存和重用结果应该会有很大帮助。当然,
ToLower()
调用可以完全从循环中取出,并存储在单独的变量中var LowerCaseFile=EntireFile.ToLower()代码>确定。在将toLower()移到循环外并进行完整的偏移后,我将再次测试性能。哇,我简直不敢相信!将ToLower()从循环中移除,并使用虚拟“子字符串”索引而不是.substring()将平均循环时间减少到1644毫秒!非常感谢你。你救了我一天:-)Ants profiler是另一种选择,两者都是在时间有限的试验中出现的。
pos = EntireFile.ToLower().IndexOf(" class", pos) + 6;
int end11 = EntireFile.ToLower().IndexOf("extends", pos);
var matches = Regex.Matchs(loweredEntireFile, " class", RegexOptions.IgnoreCase);
pos = matches.First().Index;
matches = Regex.Matchs(loweredEntireFile, "extends", RegexOptions.IgnoreCase);
var end11 = matches.First().Index;
var loweredEntiredFile = EntiredFile.ToLower();
loweredEntireFile = loweredEntireFile.Substring(pos, loweredEntireFile.Length - pos));