views:

600

answers:

3

What is the fastest built-in comparison-method for string-types in C#? I don't mind about the typographic meaning here it's only for use in sortedLists and stuff like that to search fast in large collections. I think there are only two methods: Compare and CompareOrdinal. What's the fastest?

The second question is if there is a faster method for those string-comparisons?

+13  A: 

I'm assuming you want a less-than/equal/greater-than comparison rather than just equality; equality is a slightly different topic, although the principles are basically the same. If you're actually only searching for presence in something like a SortedList, I'd consider using a Dictionary<string, XXX> instead - do you really need all that sorting?

String.CompareOrdinal, or using an overload of String.Compare which allows the comparison to be provided, and specifying an ordinal (case-sensitive) comparison, e.g. String.Compare(x, y, StringComparison.Ordinal) will be the fastest.

Basically an ordinal comparison just needs to walk the two strings, character by character, until it finds a difference. If it doesn't find any differences, and the lengths are the same, the result is 0. If it doesn't find any differences but the lengths aren't the same, the longer string is deemed "larger". If it does find a difference, it can immediately work out which is deemed "larger" based on which character is "larger" in ordinal terms.

To put is another way: it's like doing the obvious comparison between two char[] values.

Culture-sensitive comparisons have to perform all kinds of tortuous feats, depending on the precise culture you use. For an example of this, see this question. It's pretty clear that having more complex rules to follow can make this slower.

Jon Skeet
Ha: your rep currently shows the temperature of the human body (98.6).
Joel Coehoorn
@Joel: That's almost boiling ;)
280Z28
Actually, 98.6 degrees Kelvin (98.6K) is extremely cold - about -174.55 degrees Centigrade...
Jon Skeet
Downvoter: care to provide a reason?
Jon Skeet
+1  A: 

Fastest is interned strings with reference equality test, but you only get equality testing and it's at the heavy expense of memory - so expensive that it's almost never the recommended course.

Past that, a case-sensitive ordinal test will be the fastest, and this method is absolutely recommended for non-culture-specific strings. Case-sensitive is faster if it works for your use case.

When you specify either StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase, the string comparison will be non-linguistic. That is, the features that are specific to the natural language are ignored when making comparison decisions. This means the decisions are based on simple byte comparisons and ignore casing or equivalence tables that are parameterized by culture. As a result, by explicitly setting the parameter to either the StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase, your code often gains speed, increases correctness, and becomes more reliable.

Source

280Z28
+1  A: 

I Checked both the string.Compare and string.CompareOrdinal using stop watch

    --Compare Ordinal  case 1 
    Stopwatch sw = new Stopwatch();
    sw.Start();
    int x = string.CompareOrdinal("Jaswant Agarwal", "Jaswant Agarwal");
    sw.Stop();
    lblTimeGap.Text = sw.Elapsed.ToString(); 






    -- Only compare  case 2
    Stopwatch sw = new Stopwatch();
    sw.Start();
    int x = string.Compare("Jaswant Agarwal", "Jaswant Agarwal");
    sw.Stop();
    lblTimeGap.Text = sw.Elapsed.ToString();

In case 1 Average elapsed timing was 00:00:00.0000030 In case 2 Average elapsed timing was 00:00:00.0000086

I tried with different Equal and not equal combinations of string and found that every time CompareOrdinal is faster than only compare..

That is my own observation..you can also try just put two buttons on a form and copy paste this code in regrading event..

Jaswant Agarwal