2011-03-10 29 views
4

我想解析一些ddump文件,你能幫我加快我的算法嗎?
每個循環需要216 ms!這太方便了。我希望每個迴路有大約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); }

任何幫助將不勝感激。

+2

我很好奇,想知道什麼格式轉儲完成文件是。什麼是文件大小?是否有可共享的數據樣本? – 2011-03-10 15:22:47

+0

在循環之外移動'EntireFile.ToLower()'將是一個合理的開始,但是您應該向探查器詢問最受傷的位置。如果你證明了樣本數據和一個完整的工作程序,有人可能有時間玩它。 – 2011-03-10 15:25:56

+0

它是一個Nemo 440轉儲文件,但我不想最初發布它,因爲它可能會產生關於反編譯的討論... – alex 2011-03-10 15:26:56

回答

9

好,多次執行此操作

EntireFile.ToLower() 

肯定不會幫助。有幾件事情可以做:

  1. 進行昂貴的操作(ToLowerIndexOf等),只有一次,如果可能的話緩存結果。
  2. 不要縮小你用SubString處理的輸入,這會殺死你的表現。而是保留一個單獨的int parseStart值,並將其用作所有IndexOf調用的附加參數。換句話說,跟蹤您手動解析的文件部分,而不是每次都使用較小的子字符串。
+1

只需添加到此...將該方法的結果放入一個變量並重新使用它。否則,你需要整個文件,並且每次調用它時必須將所有內容處理爲小寫。 – 2011-03-10 15:23:37

+0

好的。但我需要一些子字符串來返回。 – alex 2011-03-10 15:24:57

+0

我在@Jon上。 – 2011-03-10 15:25:39

1

您的性能問題與所有字符串複製操作的開銷有很大關係。

有重載,讓你指定你的字符串操作的有效範圍,如果你通過簡單地使用一個索引來虛擬子串字符串來消除複製,那將會產生變化。

此外,不區分大小寫的比較不是通過降低或增加字符串來完成的!您可以使用StringComparer類或StringComparsion枚舉。有許多字符串重載讓你指定是否考慮區分大小寫。

使用方括號表示法重複索引字符串也非常昂貴。如果你看看.NET中字符串操作的實現,他們總是把搜索字符串變成一個char數組,因爲它更快。但是,這意味着即使對於只讀搜索操作,仍然有很多複製仍在進行。

1

我建議使用分析工具將您的代碼放在一邊,以減慢速度。

JetBrains dotTrace是一款性能卓越的產品,極大地幫助了這類任務。

+0

螞蟻分析器是另一種選擇,都在時間有限的審判。 – 2011-03-10 15:27:19

+0

由於是slimtune。請訪問http://code.google.com/p/slimtune/查看 – Davido 2011-03-10 15:30:46

1

除了Jon的回答,據我瞭解,你的代碼的while()部分中的任何內容都會在每個循環中執行。因此,您可能會更快地找出一種方法,避免重新計算

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

while循環的每次迭代。另外,你究竟想要解析什麼?這是一個正常的文本文件?你沒有提供很多細節。我喜歡用來分析文本文件的一種方法是使用'\ n'作爲分隔符將整個文件加載到一個字符串數組中。然後我可以快速瀏覽數組並解析內容。如果需要,我可以存儲數組索引並快速引用上一行。

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

需要在同時結束