2010-09-22 120 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