Быстрая стабильная сортировка для небольших массивов (до 32 или 64 элементов)

Общая мудрость гласит, что для достаточно маленьких массивов сортировка вставки является лучшей. Например, Timsort использует (двоичную) сортировку вставки для массивов до 64 элементов; от Wikipedia:

Некоторые алгоритмы разделения и покорения, такие как сортировка quicksort и mergesort, рекурсивно делят список на более мелкие подсписки, которые затем сортируются. Полезной оптимизацией на практике для этих алгоритмов является использование сортировки вставки для сортировки небольших подсписок, поскольку сортировка вставки превосходит эти более сложные алгоритмы. Размер списка, для которого сортировка вставки имеет преимущество, зависит от среды и реализации, но обычно составляет от восьми до двадцати элементов.

Это действительно правильно? Есть ли лучшие альтернативы?

В случае, если это существенно зависит от платформы, меня больше всего интересует .NET.

Ответ 1

Да, это то, что я узнал в своих классах алгоритмов, и это также то, как сортировка реализована в С++ STL. Материал из Википедии:

Стандарт SGI С++ в июне 2000 года Библиотека шаблонов stl_algo.h использование нестабильной сортировки интросорный подход Муссера с глубина рекурсии для переключения на хаппорт передается как параметр, медианный из 3 выбор поворота и Sedgewick окончательная вставка сортировка. Элемент порог для переключения на простой вставка сортировка была 16.

В прошлом году я провел некоторые неофициальные тесты производительности, а С++ STL std:: sort был примерно в два раза быстрее, чем Array.Sort в .NET. Я не знаю, как реализован .NET Array.Sort, но в .NET доступ в массиве требует проверки границ, в отличие от С++, что может в значительной степени учитывать разницу в производительности.

Ответ 2

Я нашел, что это действительно зависит от того, какую работу должна выполнять функция сравнения. Например, если я косвенно сортирую строки рабочего листа, и каждое сравнение включает выборку строки, а затем сравнение возможно нескольких столбцов, возможно, смешивание числовых и строковых сравнений, оно может замедляться.

С другой стороны, если длина массива коротка, это зависит от того, сколько раз в секунду вам нужно ее сортировать, потому что, даже если она относительно медленная по сравнению с тем, что она может быть, вы никогда не заметите, разница.

Если у меня есть какие-либо сомнения, я просто кодирую сортировку слияния и соглашаюсь с этим. У меня был плохой опыт, когда qsort не был стабильным и иногда занимал много времени. Ручная сортировка слияния проста, надежна и достаточно быстро.

Ответ 3

Не существует более быстрых алгоритмов O (n log n), чем сортировка вставки для небольших списков. Однако существуют некоторые алгоритмы O (n ^ 2), которые конкурируют. Примечательно, что выбор сортировки не является одним из них, хотя он хорош в редкой ситуации, когда свопы и ходы дороги. Сортировка и варианты Bubble также просто плохие.

Сортировка сети: алгоритм сортировки, всегда стабильный, без ветвей. У этого есть ужасные спецификации в целом, но ни одна из ветвей не означает звездную производительность в самых маленьких списках. Основной корпус: if(a<b) swap(a,b);

Сортировка вставки с партиями: в каждом цикле отберите 2-4 элемента, затем вставьте их вместе. Это уменьшает количество ходов и сравнивает их на 25-37 процентов для более длинных списков. Общий эффект - оптимизация для списков в диапазоне размеров от 16 до 64.

Ответ 4

Так как .NET - это язык, который не компилируется в raw machinecode. Я бы сказал, что вызов функции API (который использует собственный код), вероятно, является самым быстрым способом перехода