When you are comparing 2 strings, in most cases the “bog standard” parameters are fine. However, if you are using your comparison in a sort operation which will be iterated many many times, you will get a better performance if you use one of the overloads which takes a StringComparison enumeration (or a CompareOptions enumeration, if you are using a Comparer object).
Take the following example, where I have iterated the Person.Contact table of the AdventureWorks database one million times. (As that table contains 19,972 tuples, the comparison method is hit 19,972 x 1 million times.)
static void Main(string[] args)
{
CompareInfo myCompare = CultureInfo.InvariantCulture.CompareInfo;
AdventureWorksDataSetTableAdapters.ContactTableAdapter da = new AdventureWorksDataSetTableAdapters.ContactTableAdapter();
AdventureWorksDataSet.ContactDataTable dt = da.GetData();
List<string> names = new List<string>();
for (int i = 0; i < dt.Rows.Count; ++i)
{
names.Add(dt.Rows[i][5].ToString());
}
string[] namesArr = names.ToArray();
Console.WriteLine("\nData in. Press any key to compare...\n");
Console.ReadKey();
Console.WriteLine("\nGo\n");
Stopwatch watch = new Stopwatch();
watch.Start();
for (int l = 0; l < 1000000; ++l)
{
for (int i = 0; i < namesArr.Length; ++i)
{
//Console.WriteLine("Rogers".CompareTo(dt.Rows[i][5].ToString()));
myCompare.Compare("Rogers", namesArr[i], CompareOptions.Ordinal);
//string.Compare("Rogers", namesArr[i], StringComparison.OrdinalIgnoreCase);
//Console.WriteLine(string.Compare("Rogers", namesArr[i]));
}
}
watch.Stop();
Console.WriteLine(watch.Elapsed);
Console.WriteLine("\nPress any key to quit...");
Console.Read();
}
If you pass the CompareOptions.Ordinal enumeration, the strings are compared using their Unicode value (which is much faster than a linguistic comparison). However, you do have to be a bit careful, as that does not take case into account – for example, it would consider “Zappa” to come before “abba”. But have no fear, as StringComparison.OrdinalIgnoreCase does take case into account.
I ran a few tests to see the different kinds of performance times for the various StringComparison options:
CompareOptions.Ordinal – 08:26m
StringComparison.OrdinalIgnoreCase -10:03m
Default linguistic comparison – 31:52m
As you can see, there is a pretty significant performance increase over the linguistic comparison.
Also, note that there is an overload of the constructor for generic Dictionaries which takes a StringComparer enumeration. This will make lookups on a Dictionary, which uses strings as keys, very quick :-
Dictionary<string, bool> someDictObject = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
So think carefully about what you need to achieve when selecting the best overload for string comparisons running in high-iteration scenarios.

