Почему List <T> .Sort использует Comparer <int> .Default более чем в два раза быстрее аналогичного пользовательского компаратора?
Используя список из 10 миллионов случайныхint
s (одно и то же семя каждый раз, в среднем 10 повторений):
listCopy.Sort(Comparer<int>.Default)
принимает314ms.
С помощью
sealed class IntComparer : IComparer<int>
{
public int Compare(int x, int y)
{
return x < y ? -1 : (x == y ? 0 : 1);
}
}
listCopy.Sort(new IntComparer())
принимает716ms.
Некоторые варианты:
Usingstruct IntComparer
instead of sealed class
: 771ms
Using public int Compare(int x, int y) { return x.CompareTo(y); }
: 809ms
Comments
Comparer<int>.Default
возвращаетGenericComparer<int>
, Согласно dotPeek у нас есть:
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;
}
...
}
Очевидно, что это не должно быть быстрее, чем мойIntComparer
вариант с использованиемCompareTo
.
Я не нашел ничего релевантного вArraySortHelper<T>
который, кажется, является ядромList<T>.Sort
.
Я могу только догадываться, что JIT делает здесь какой-то магический специальный корпус (Замените сортировки, которые используютComparer<int>.Default
специализированной реализацией сортировки, которая не делаетIComparer<T>.Compare
звонки или что-то подобное)?
РЕДАКТИРОВАТЬ: сроки выше, слишком низок в5.9214729782462845
(Stopwatch
а такжеTimeSpan
имеют другое определение «Tick»). Однако это не влияет на данный момент.