2010-02-26 103 views
4

任何人都可以幫助我如何優化這種方法嗎?字符串替換方法的優化

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
{ 
    VirtualPathData path = base.GetVirtualPath(requestContext, values); 

    if (path != null) 
    { 
     string virtualPath = path.VirtualPath; 
     string condition = string.Empty; 

     if (virtualPath.Contains("?")) 
     { 
      condition = virtualPath.Substring(virtualPath.IndexOf("?")); 
      virtualPath = virtualPath.Substring(0, virtualPath.IndexOf("?")); 
     } 

     virtualPath = virtualPath.Replace(@"%C5%BD", "ž"); 
     virtualPath = virtualPath.Replace(@"%C4%90", "đ"); 
     virtualPath = virtualPath.Replace(@"%C4%86", "ć"); 
     virtualPath = virtualPath.Replace(@"%C4%8C", "č"); 
     virtualPath = virtualPath.Replace(@"%C5%A0", "š"); 

     virtualPath = virtualPath.ToLower().Replace(",", "-").Replace("%20", "-").Replace("&", "-"); 
     virtualPath = virtualPath.Replace(@"-amp;", "&"); 

     while (virtualPath.Contains("--")) 
     { 
      virtualPath = virtualPath.Replace("--", "-"); 
     } 

     path.VirtualPath = virtualPath + condition; 
    } 

    return path; 
} 

回答

4

在此代碼中要掃描的字符串三次字符:

if (virtualPath.Contains("?")) 
{ 
    condition = virtualPath.Substring(virtualPath.IndexOf("?")); 
    virtualPath = virtualPath.Substring(0, virtualPath.IndexOf("?")); 
} 

相反,一次掃描,並使用結果的三倍。同時掃描一個字符,而不是一個字符串:

int pos = virtualPath.IndexOf('?'); 
if (pos != -1) { 
    condition = virtualPath.Substring(pos); 
    virtualPath = virtualPath.Substring(0, pos); 
} 

在這裏,你正在做的幾個替換相同的替換:

virtualPath = virtualPath.ToLower().Replace(",", "-").Replace("%20", "-").Replace("&", "-"); 

相反,你可以使用正則表達式匹配所有的人:

virtualPath = Regex.Replace(virtualPath.ToLower(), "(,|%20|&)", "-"); 

(這是否實際提供更好的性能必須用您的一些實際數據進行測試。儘管它已經是少操作,有設立正規expresson一些開銷)


您正在使用一個循環來減少字符集羣:

while (virtualPath.Contains("--")) 
{ 
    virtualPath = virtualPath.Replace("--", "-"); 
} 

相反,你可以使用正則表達式做一個單一的替換:

virtualPath = Regex.Replace(virtualPath, "-{2,}", "-"); 
+0

您也可以將' - {2,}'表達式合併到另一個:'(,|%20 |&| - {2,})' – 2010-02-26 14:03:10

+0

@Joel,我不能合併它,因爲if我的輸入是'foo&foo',輸出將是'foo --- foo'。 – 2010-02-26 14:13:16

0

你最明顯的第一步是使用StringBuilder而不是String。

字符串是不可變的類型。這意味着一旦創建,它的價值永遠不會改變。因此,對於您在方法中進行的每次替換調用,程序將創建一個全新的String實例來存儲結果,這是存儲器和處理器密集型的。 (我這樣說比較 - 你不會讓你的機器最大限度地調用這個方法一次,但如果你稱它爲數千次,你一定會注意到!)

另一方面,StringBuilder一個設計用於在內存中操作字符串的類,每次更改字符串時都不必複製/重新創建內存。

因此,在正確的方向上的一個大的步驟應該是在你的方法開始使用此:

  StringBuilder sb = new StringBuilder(path.VirtualPath.ToLower()); 
      string condition = string.Empty; 

      int index = path.VirtualPath.IndexOf("?"); 

      if (index > -1) 
      { 
       condition = virtualPath.Substring(pos); 
       sb.Remove(0, index); 
      } 

      sb.Replace(@"%C5%BD", "ž") 
       .Replace(@"%C4%90", "đ") 
       .Replace(@"%C4%86", "ć") 
       .Replace(@"%C4%8C", "č") 
       .Replace(@"%C5%A0", "š") 
       .Replace(",", "-") 
       .Replace("%20", "-") 
       .Replace("&", "-") 
       .Replace(@"-amp;", "&"); 
      sb.Append(condition); 

請注意,我也做了.ToLower(早期),因爲StringBuilder的不具有相當於,並且還注意到sb.Append,這又會阻止很多重寫。

這是不是最佳的,因爲它可以得到的,但它應該是相當的改善...

有一件事我錯過了被取代的「 - 」。 StringBuilder沒有「Contains」函數,但是您可以使用正則表達式在一次傳遞中捕獲所有內容(而不是需要循環)。

希望能讓你開始!

相關問題