2011-02-06 54 views
0

我有簡單的方法在C#:之間的兩串

public static string BetweenOf(string ActualStr, string StrFirst, string StrLast) 
     { 
      return ActualStr.Substring(ActualStr.IndexOf(StrFirst) + StrFirst.Length, (ActualStr.Substring(ActualStr.IndexOf(StrFirst))).IndexOf(StrLast) + StrLast.Length); 
     } 

如何優化呢?

+1

定義 「優化」。 – BoltClock 2011-02-06 07:23:37

+1

我想仔細的代碼分析告訴你這種方法實際上是應用程序性能的瓶頸? – 2011-02-06 07:25:00

+0

相關:http://stackoverflow.com/questions/4190533/how-to-find-substring-from-string-without-using-indexof-method-in-c – 2011-02-06 07:25:50

回答

2

下面是@Chris here代碼是如何棧對正則表達式測試:

void Main() 
{ 
    string input = "abcdefghijklmnopq"; 
    string first = "de"; 
    string last = "op"; 
    Regex re1 = new Regex("de(.*)op", RegexOptions.None); 
    Regex re2 = new Regex("de(.*)op", RegexOptions.Compiled); 

    // pass 1 is JIT preheat 
    for (int pass = 1; pass <= 2; pass++) 
    { 
     int iterations = 1000000; 
     if (pass == 1) 
      iterations = 1; 

     Stopwatch sw = Stopwatch.StartNew(); 
     for (int index = 0; index < iterations; index++) 
      BetweenOfFixed(input, first, last); 
     sw.Stop(); 
     if (pass == 2) 
      Debug.WriteLine("IndexOf: " + 
       sw.ElapsedMilliseconds + "ms"); 

     sw = Stopwatch.StartNew(); 
     for (int index = 0; index < iterations; index++) 
      BetweenOfRegexAdhoc(input, first, last); 
     sw.Stop(); 
     if (pass == 2) 
      Debug.WriteLine("Regex adhoc: " + 
       sw.ElapsedMilliseconds + "ms"); 

     sw = Stopwatch.StartNew(); 
     for (int index = 0; index < iterations; index++) 
      BetweenOfRegexCached(input, first, last); 
     sw.Stop(); 
     if (pass == 2) 
      Debug.WriteLine("Regex uncompiled: " + 
       sw.ElapsedMilliseconds + "ms"); 

     sw = Stopwatch.StartNew(); 
     for (int index = 0; index < iterations; index++) 
      BetweenOfRegexCompiled(input, first, last); 
     sw.Stop(); 
     if (pass == 2) 
      Debug.WriteLine("Regex compiled: " + 
       sw.ElapsedMilliseconds + "ms"); 
    } 
} 

public static string BetweenOfFixed(string ActualStr, string StrFirst, 
    string StrLast) 
{ 
    int startIndex = ActualStr.IndexOf(StrFirst) + StrFirst.Length; 
    int endIndex = ActualStr.IndexOf(StrLast, startIndex); 
    return ActualStr.Substring(startIndex, endIndex - startIndex); 
} 

public static string BetweenOfRegexAdhoc(string ActualStr, string StrFirst, 
    string StrLast) 
{ 
    // I'm assuming you don't replace the delimiters on every call 
    Regex re = new Regex("de(.*)op", RegexOptions.None); 
    return re.Match(ActualStr).Groups[1].Value; 
} 

private static Regex _BetweenOfRegexCached = 
    new Regex("de(.*)op", RegexOptions.None); 
public static string BetweenOfRegexCached(string ActualStr, string StrFirst, 
    string StrLast) 
{ 
    return _BetweenOfRegexCached.Match(ActualStr).Groups[1].Value; 
} 

private static Regex _BetweenOfRegexCompiled = 
    new Regex("de(.*)op", RegexOptions.Compiled); 
public static string BetweenOfRegexCompiled(string ActualStr, string StrFirst, 
    string StrLast) 
{ 
    return _BetweenOfRegexCompiled.Match(ActualStr).Groups[1].Value; 
} 

輸出:

IndexOf: 1419ms 
Regex adhoc: 7788ms 
Regex uncompiled: 1074ms 
Regex compiled: 682ms
2

你可以構造一個正則表達式:

var regex = strFirst + "(.*)" + strLast; 

你的文本將是第一個(也是唯一一個)捕捉之間的匹配。

0

如何使用正則表達式?這可能比創建臨時字符串更快。 此外,這可以輕鬆地輕鬆地處理沒有找到這種字符串的情況。

4

如果我明白你想要做什麼,我認爲你的實現可能是不正確的。

這是一個我認爲至少在GC方面表現更好的實現,因爲它不會使用多個對SubString的調用,這些調用會在堆上創建僅臨時使用的新字符串。

public static string BetweenOfFixed(string ActualStr, string StrFirst, string StrLast) 
{ 
    int startIndex = ActualStr.IndexOf(StrFirst) + StrFirst.Length; 
    int endIndex = ActualStr.IndexOf(StrLast, startIndex); 
    return ActualStr.Substring(startIndex, endIndex - startIndex); 
} 

比較這個與正則表達式解決方案的性能會很有趣。

相關問題