2010-09-22 182 views
6

我會解釋我的問題(請原諒我的英語不好),我有一個.NET的exe在處理每毫秒是非常重要的。字符串比較4

該程序做了大量的字符串比較(大部分是string1.IndexOf(string2, StringComparison.OrdinalIgnoreCase))。

當我切換到框架4,我的節目時間是比以前的兩倍。

我搜索瞭解釋,並且我發現函數IndexOf(s, OrdinalIgnoreCase)在框架4中的速度要慢得多(我用一個簡單的控制檯應用程序進行了測試,並且在循環中,時間爲3.5ms,時間爲30ms,在4.0時爲210ms)。但是在框架4中,當前文化的比較速度比3.5快。

在這裏它的代碼示例使用:

int iMax = 100000; 
String str = "Mozilla/5.0+(Windows;+U;+Windows+NT+5.1;+fr;+rv:1.9.0.1)+Gecko/2008070208+Firefox/3.0.1"; 
Stopwatch sw = new Stopwatch(); 
sw.Start(); 
StringComparison s = StringComparison.OrdinalIgnoreCase; 
for(int i = 1;i<iMax;i++) 
{ 
    str.IndexOf("windows", s); 
} 
sw.Stop(); 
Console.WriteLine(sw.ElapsedMilliseconds); 
Console.Read(); 

我的問題是:

  1. 有沒有人注意到了同樣的問題?

  2. 有人對這個改變有解釋嗎?

  3. 有沒有解決方案來繞過問題?

謝謝。

+0

基於字符類型或字符串類型的字符串參數? – ChrisBD 2010-09-23 06:22:43

+0

字符串參數 – baz 2010-09-23 08:03:29

回答

5

好吧,我有我的問題的一個迴應。

用反射器我可以看到框架2和4之間的差異,這解釋了我的perforamnce問題。

public int IndexOf(string value, int startIndex, int count, StringComparison comparisonType) 
{ 
    if (value == null) 
    { 
     throw new ArgumentNullException("value"); 
    } 
    if ((startIndex < 0) || (startIndex > this.Length)) 
    { 
     throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index")); 
    } 
    if ((count < 0) || (startIndex > (this.Length - count))) 
    { 
     throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count")); 
    } 
    switch (comparisonType) 
    { 
     case StringComparison.CurrentCulture: 
      return CultureInfo.CurrentCulture.CompareInfo.IndexOf(this, value, startIndex, count, CompareOptions.None); 

     case StringComparison.CurrentCultureIgnoreCase: 
      return CultureInfo.CurrentCulture.CompareInfo.IndexOf(this, value, startIndex, count, CompareOptions.IgnoreCase); 

     case StringComparison.InvariantCulture: 
      return CultureInfo.InvariantCulture.CompareInfo.IndexOf(this, value, startIndex, count, CompareOptions.None); 

     case StringComparison.InvariantCultureIgnoreCase: 
      return CultureInfo.InvariantCulture.CompareInfo.IndexOf(this, value, startIndex, count, CompareOptions.IgnoreCase); 

     case StringComparison.Ordinal: 
      return CultureInfo.InvariantCulture.CompareInfo.IndexOf(this, value, startIndex, count, CompareOptions.Ordinal); 

     case StringComparison.OrdinalIgnoreCase: 
      return TextInfo.IndexOfStringOrdinalIgnoreCase(this, value, startIndex, count); 
    } 
    throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType"); 
} 

這是2框架的功能的IndexOf的基本代碼(4之間沒有差異和2)

但在功能TextInfo.IndexOfStringOrdinalIgnoreCase有差異:

框架2:

internal static unsafe int IndexOfStringOrdinalIgnoreCase(string source, string value, int startIndex, int count) 
{ 
    if (source == null) 
    { 
     throw new ArgumentNullException("source"); 
    } 
    return nativeIndexOfStringOrdinalIgnoreCase(InvariantNativeTextInfo, source, value, startIndex, count); 
} 

框架4:

internal static int IndexOfStringOrdinalIgnoreCase(string source, string value, int startIndex, int count) 
{ 
    if ((source.Length == 0) && (value.Length == 0)) 
    { 
     return 0; 
    } 
    int num = startIndex + count; 
    int num2 = num - value.Length; 
    while (startIndex <= num2) 
    { 
     if (CompareOrdinalIgnoreCaseEx(source, startIndex, value, 0, value.Length, value.Length) == 0) 
     { 
      return startIndex; 
     } 
     startIndex++; 
    } 
    return -1; 
} 

主要算法已在架構改變2呼叫是nativeDll已經框架4. 的去除其良好的知道

0

我不能回答你的具體.NET 4的速度問題。

但是你可能會獲得更多的速度改善你的算法。檢查出Rabin-Karp string search algo

+0

是的,我可以使用另一個算法,但我想知道爲什麼框架4比框架2慢。我檢查了拉賓卡爾普感謝 – baz 2010-09-23 08:12:26

+0

我不能說從某些點來說它已被認爲是更快。可能是其他人的速度較慢。 – Wernight 2010-09-23 08:19:19