加速解析算法

时间:2011-03-10 15:14:39

标签: c# algorithm parsing refactoring

我正在尝试解析一些ddump文件,请你帮我加快算法速度? 每个循环需要216毫秒!!这太过分了。我希望每循环大约40-50毫秒。也许使用RegExp?

这是我的algrithm:

 while (pos < EntireFile.Length && (/*curr = */EntireFile.Substring(pos, EntireFile.Length - pos)).Contains(" class"))
            {
                w.Reset();
                w.Start();
                pos = EntireFile.ToLower().IndexOf(" class", pos) + 6;
                int end11 = EntireFile.ToLower().IndexOf("extends", pos);
                if (end11 == -1)
                    end11 = EntireFile.IndexOf("\r\n", pos);
                else
                {
                    int end22 = EntireFile.IndexOf("\r\n", pos);
                    if (end22 < end11)
                        end11 = end22;
                }
                //string opcods = EntireFile.Substring(pos, EntireFile.Length - pos);
                string Cname = EntireFile.Substring(pos, end11 - pos).Trim();
                pos += (end11 - pos) + 7;
                pos = EntireFile.IndexOf("{", pos) +1;

int count = 1; string searching = EntireFile.Substring(pos, EntireFile.Length - pos); int searched = 0; while (count != 0) { if (searching[searched] == '{') count++; else if (searching[searched] == '}') count--; searched++; } string Content = EntireFile.Substring(pos, searched); tlist.Add(new TClass() { ClassName = Cname, Content = Content }); pos += searched; if (pos % 3 == 0) { double prc = ((double)pos) * 100d / ((double)EntireFile.Length); int prcc = (int)Math.Round(prc); wnd.UpdateStatus(prcc); wnd.Update(); } mils.Add((int)w.ElapsedMilliseconds); }

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:9)

好吧,多次这样做

EntireFile.ToLower()
肯定无济于事。你可以做几件事:

  1. 仅执行一次代价高昂的操作(ToLowerIndexOf等)并尽可能缓存结果。
  2. 请勿缩小您使用SubString处理的输入,否则会导致性能下降。而是保留单独的int parseStart值,并将其用作所有IndexOf次调用的附加参数。换句话说,跟踪手动解析的文件部分,而不是每次都使用较小的子字符串。

答案 1 :(得分:1)

您遇到的性能问题与所有字符串复制操作的开销有很大关系。

如果通过简单地使用索引来虚拟地对整个字符串进行子字符串来消除复制,那么有一些重载可以指定字符串操作的有效范围。

此外,不通过降低或增加字符串来进行不区分大小写的比较!您使用StringComparer类或StringComparsion枚举。有许多字符串重载,您可以指定是否考虑区分大小写。

使用方括号表示法重复索引字符串也非常昂贵。如果你看一下.NET中字符串操作的实现,他们总是把搜索字符串变成一个char数组,因为这样做起来更快。但是,这意味着即使对于只读搜索操作,仍然会进行大量复制。

答案 2 :(得分:1)

我建议使用分析工具将代码部分归零,这会降低您的速度。

JetBrains dotTrace是一款分析产品,它非常有助于完成这项任务。

答案 3 :(得分:1)

除了Jon的答案之外,据我所知,代码中while()部分的任何内容都将在每个循环中执行。所以你可能会更快找到一种不重新计算的方法

EntireFile.Substring(pos, EntireFile.Length - pos)).Contains(" class")

在while循环的每次迭代中。另外,你究竟要解析什么?它是普通的文本文件吗?你没有提供很多细节。我想用来解析文本文件的一种方法是使用'\ n'作为分隔符将整个文件加载到字符串数组中。然后我可以快速浏览数组并解析内容。如果需要,我可以存储数组索引并快速引用前一行。

答案 4 :(得分:1)

首先,你可以改变

while (pos < EntireFile.Length && (/*curr = */EntireFile.Substring(pos, EntireFile.Length - pos)).Contains(" class"))
{
 ...
}

var loweredEntireFile = EntireFile.ToLower();

while (pos < loweredEntireFile.Length && 
       Regex.IsMatch(loweredEntireFile, " class",   
       RegexOptions.IgnoreCase)
{
...

    // we just need to process the rest of the file
    loweredEntireFile = loweredEntireFile.Substring(pos, loweredEntireFile.Length - pos));
}

然后改变

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));

需要在while结束时完成