Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 加速解析算法_C#_Algorithm_Parsing_Refactoring - Fatal编程技术网

C# 加速解析算法

C# 加速解析算法,c#,algorithm,parsing,refactoring,C#,Algorithm,Parsing,Refactoring,我正在解析一些ddump文件,你能帮我加快算法吗? 每个循环需要216毫秒!!这太过分了。我想让它大约40-50毫秒每循环。也许通过使用RegExp 这是我的忠告: 任何帮助都将不胜感激。好吧,请多次这样做 EntireFile.ToLower() 当然不会有帮助。您可以做以下几件事: 仅执行一次代价高昂的操作(ToLower,IndexOf等),并尽可能缓存结果 不要缩小使用子字符串处理的输入范围,这会降低性能。相反,保留一个单独的intparsestart值,并将其用作所有IndexO

我正在解析一些ddump文件,你能帮我加快算法吗?
每个循环需要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));