6

I will explain my problem(excuse my bad English), I have a .NET exe in which every milliseconds of processing is very important.

This program does lots of string comparison (most of it is string1.IndexOf(string2, StringComparison.OrdinalIgnoreCase)).

When i switch to framework 4, my program time is twice than before.

I searched for explanation and I found that the function IndexOf(s, OrdinalIgnoreCase) is much slower in framework 4 (I did test with a simple console application and in a loop the time was 30ms in 3.5 and 210ms in 4.0 ???). But the comparison in current culture is quicker in framework 4 than 3.5.

Here it's a sample of code I use :

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();

My questions are :

  1. Has anyone noticed the same problem?

  2. Someone have an explanation on this change?

  3. Is there a solution to bypass the problem?

Thanks.

1
  • Are your string parameters based on char types or string types? Commented Sep 23, 2010 at 6:22

3 Answers 3

5

Ok i have a response of one of my question.

With reflector i can see the difference between framework 2 and 4 and that explain my perforamnce issue.

    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");
}

This is the base code of function IndexOf of the 2 framework (no difference between 4 and 2)

But in the function TextInfo.IndexOfStringOrdinalIgnoreCase there are differences :

Framework 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);
}

Framework 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;
}

The main algorithm has changed in framework 2 the call is a nativeDll that has been removed of framework 4. Its good to know

Sign up to request clarification or add additional context in comments.

Comments

1

This is a known issue in .NET 4.

Here is the MS Connect report.

Comments

0

I cannot answer on your specific .NET 4 speed issue.

However you'd probably gain much more speed by improving your algo. Check out the Rabin-Karp string search algo.

2 Comments

Yes i can use another algo but i want to know why framework 4 is slower than framework 2. I check out the Rabin-Karp thanks
I cant tell that from some points it has been said to be faster. May be it's slower on others.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.