Results

Using a list of 10 million random ints (same seed each time, average of 10 repetitions):

listCopy.Sort(Comparer<int>.Default) takes 314ms.

Using

sealed class IntComparer : IComparer<int>
{
  public int Compare(int x, int y)
  {
    return x < y ? -1 : (x == y ? 0 : 1);
  }
}

listCopy.Sort(new IntComparer()) takes 716ms.

Some variations:

  • Using struct IntComparer instead of sealed class: 771ms
  • Using public int Compare(int x, int y) { return x.CompareTo(y); }: 809ms

Comments

Comparer<int>.Default returns a GenericComparer<int>. According to dotPeek, we have:

internal class GenericComparer<T> : Comparer<T> where T : IComparable<T>
{
  public override int Compare(T x, T y)
  {
    if ((object) x != null)
    {
      if ((object) y != null)
        return x.CompareTo(y);
      else
        return 1;
    }
    else
      return (object) y != null ? -1 : 0;
  }

...
}

Obviously, this shouldn't be faster than my IntComparer variant using CompareTo.

I didn't find anything relevant in ArraySortHelper<T>, which appears to be the core of List<T>.Sort.

I can only guess that the JIT does some magic special-casing here (Replace sorts which use Comparer<int>.Default by a specialized sorting implementation which doesn't do any IComparer<T>.Compare calls, or something similar)?

EDIT: The timings above are too low by a factor of 5.9214729782462845 (Stopwatch and TimeSpan have a different definition of "Tick"). Doesn't affect the point, though.

Edit
Report