Ваши результаты будут очень сильно зависеть от типа T
и от того, насколько дорогими будут сравнения.
Я создал пользовательские версии ваших QuickSort
методов: тот, который ожидает массив int
, и тот, который ожидает массив string
. Изменения ограничиваются удалением параметра сравнения и изменением двух сравнений в разделителе. Я изменил их для сортировки в обратном порядке, например:
while (i < arr.Length && arr[i].CompareTo(x) > 0) i++;
while (j >= 0 && arr[j].CompareTo(x) < 0) j--;
Затем я проверил эти методы на вашем общем методе, используя массивы из 10 миллионов элементов. Мои результаты:
Int: Generic QuickSort - 2,190 ms
Int: Custom QuickSort - 1,252 ms
String: Generic QuickSort - 32,902 ms
String: Custom QuickSort - 31,634 ms
Мой вывод таков: если сравнение очень недорогое (как с int
и другими нативными типами), то вы заметите большую разницу в производительности. Если сравнение дорого (строки довольно дороги для сравнения), то затраты на виртуальный вызов теряются в стоимости сравнения.
Я знаю, что это не дает решения вашей проблемы; Я не думаю, что есть один. Гибкость часто приходит за деньги.
Люди, которые создавали библиотеки базовых классов, это понимали. Например, они создали особые случаи для примитивных типов, которые используют значение по умолчанию IComparer
. Сравните разницу во времени выполнения при вызове Array.Sort
этими двумя способами (используя int[10000000]
):
Array.Sort(a); // 845 ms
Array.Sort(a, (a, b) => a.CompareTo(b)); // 2,339 ms
Оказывается, что Array.Sort
имеет встроенные оптимизации для примитивных типов, которые используют их по умолчанию IComparer
. См. Сравнения и IComparer для получения дополнительной информации об этом.