dotnet框架中的字符串比较4

时间:2010-09-22 15:42:50

标签: visual-studio string .net-4.0 comparison performance

我将解释我的问题(请原谅我糟糕的英语),我有一个.NET exe,其中每毫秒的处理非常重要。

这个程序进行了大量的字符串比较(大多数是string1.IndexOf(string2, StringComparison.OrdinalIgnoreCase))。

当我切换到框架4时,我的程序时间是以前的两倍。

我搜索了解释,我发现函数IndexOf(s, OrdinalIgnoreCase)在框架4中慢得多(我用一个简单的控制台应用程序进行测试,在一个循环中,时间是3.5毫秒30毫秒,4.0毫秒210毫秒? )。但是当前文化中的比较在框架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. 是否有解决问题的方法?

  4. 感谢。

3 个答案:

答案 0 :(得分:5)

好的,我的回答是我的一个问题。

使用反射器,我可以看到框架2和4之间的区别,这可以解释我的性能问题。

    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中已更改,调用是已删除框架4的nativeDll。 很高兴知道

答案 1 :(得分:1)

这是.NET 4中的一个已知问题。

Here is the MS Connect report

答案 2 :(得分:0)

我无法解答您特定的.NET 4速度问题。

然而,你可能会通过改善算法来获得更快的速度。查看Rabin-Karp string search algo