Possible Duplicate:
String comparison in dotnet framework 4
I noticed a performance problem on my machine in a UI app that is doing lots of string comparisons to do filtering of large lists. I tracked the issue down to using OrdinalIgnoreCase in a call to string.IndexOf. The following benchmarks were run in Release without the debugger attached, it's a 4.0 project built in VS 2010, windows 7, I do have the 4.5 beta installed on this machine, I'm not sure if that would affect this.
1.190 seconds for OrdinalIgnoreCase
0.178 seconds for CurrentCultureIgnoreCase
0.175 seconds for InvariantCultureIgnoreCase
0.101 seconds for Ordinal
0.132 seconds for CurrentCulture
0.126 seconds for InvariantCulture
1.176 seconds for OrdinalIgnoreCase
0.189 seconds for CurrentCultureIgnoreCase
0.183 seconds for InvariantCultureIgnoreCase
0.104 seconds for Ordinal
0.138 seconds for CurrentCulture
0.127 seconds for InvariantCulture
As you can see OrdinalIgnoreCase is over 6.5x slower! But without IgnoreCase Ordinal is the fastest. In multiple places microsoft recommends OrdinalIgnoreCase for the best performance. Can anyone replicate these results or explain why OrdinalIgnoreCase is going so much slower in this test?
private static void Test(string search, string key, StringComparison comparison, int trials)
{
var sw = Stopwatch.StartNew();
for (int i = 0; i < trials; i++)
{
search.IndexOf(key, comparison);
}
Console.WriteLine("{0:0.000} seconds for {1}", sw.ElapsedMilliseconds / 1000.0, comparison);
}
static void Main(string[] args)
{
int trials = 1000000;
var search = Guid.NewGuid().ToString("N");
var key = "34";
Test(search, key, StringComparison.OrdinalIgnoreCase, trials);
Test(search, key, StringComparison.CurrentCultureIgnoreCase, trials);
Test(search, key, StringComparison.InvariantCultureIgnoreCase, trials);
Test(search, key, StringComparison.Ordinal, trials);
Test(search, key, StringComparison.CurrentCulture, trials);
Test(search, key, StringComparison.InvariantCulture, trials);
Test(search, key, StringComparison.OrdinalIgnoreCase, trials);
Test(search, key, StringComparison.CurrentCultureIgnoreCase, trials);
Test(search, key, StringComparison.InvariantCultureIgnoreCase, trials);
Test(search, key, StringComparison.Ordinal, trials);
Test(search, key, StringComparison.CurrentCulture, trials);
Test(search, key, StringComparison.InvariantCulture, trials);
}
NET 4.0 - IndexOf no longer uses Ordinal Comparison and so Contains can be faster.
InvariantCultureIgnoreCase uses comparison rules based on english, but without any regional variations. This is good for a neutral comparison that still takes into account some linguistic aspects. OrdinalIgnoreCase compares the character codes without cultural aspects.
OrdinalIgnoreCase members of the new StringComparison enumeration. These enforce a byte-by-byte comparison similar to strcmp that not only avoids bugs from linguistic interpretation of essentially symbolic strings, but provides better performance.
The StringComparer returned by the CurrentCultureIgnoreCase property can be used when strings are linguistically relevant but their case is not. For example, if strings are displayed to the user but case is unimportant, culture-sensitive, case-insensitive string comparison should be used to order the string data.
This is apparently a known performance problem in .net 4, I found this bug entry on connect.microsoft.com
And there is a response
Posted by Microsoft on 2/10/2012 at 11:43 AM We were able to repro this issue. The issue has been resolved and the fix will be in the next release. Thank you for you feedback.
I'm not sure what the next release will be, I will just prefer using InvariantCultureIgnoreCase instead
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With