Быстрая реализация алгоритма для сортировки очень малого списка

Это проблема, с которой я столкнулся давно. Я думал, что могу попросить твои идеи. предположим, что у меня очень маленький список чисел (целых чисел), 4 или 8 элементов, которые нужно сортировать быстро. что было бы лучшим подходом/алгоритмом?

мой подход состоял в том, чтобы использовать функции max/min (10 функций для сортировки 4 чисел, без ветвей, iirc).

// s(i,j) == max(i,j), min(i,j)
i,j = s(i,j)
k,l = s(k,l)
i,k = s(i,k) // i on top
j,l = s(j,l) // l on bottom
j,k = s(j,k)

Я думаю, мой вопрос больше касается реализации, а не типа алгоритма.

В этот момент он становится зависимым от аппаратного обеспечения, поэтому допустим 64-разрядный процессор Intel с SSE3.

Спасибо

Ответ 1

Для небольших массивов, подобных этому, вы должны, вероятно, изучить сортировочные сети. Как вы можете видеть на этой странице, сортировка вставки может быть выражена как сортирующая сеть. Однако, если вы заранее знаете размер массива, вы можете разработать оптимальную сеть. Взгляните на этот сайт, который поможет вам найти оптимальные сети сортировки для заданного размера массива (хотя оптимальное гарантируется только до размер 16, я считаю). Компараторы даже сгруппированы в операции, которые могут выполняться параллельно. Компараторы по сути такие же, как и ваши функции s (x, y), хотя, если вы действительно хотите, чтобы это было быстро, вы не должны использовать min и max, потому что тогда вы делаете вдвое больше необходимых сравнений.

Если вам нужен этот алгоритм сортировки для работы с широким диапазоном размеров, то вы, вероятно, должны просто пойти с сортировкой вставки, как предложили другие.

Ответ 2

Я вижу, что у вас уже есть решение, использующее 5 сравнений (предполагая, что s (i, j) сравнивает два числа один раз и заменяет их или нет). Если вы придерживаетесь сортировки на основе сравнения, вы не можете сделать это с менее чем 5 сравнениями.

Это можно доказать, потому что есть 4!= 24 возможных способа заказать 4 номера. Каждое сравнение может только сократить возможности пополам, поэтому при 4 сравнениях вы можете различать только 2 ^ 4 = 16 возможных порядков.

Ответ 3

Для сортировки небольших количеств нужного вам простого алгоритма, поскольку сложность добавляет дополнительные накладные расходы.

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

function sort(i,j,k,l) {
  if (i < j) {
    if (j < k) {
      if (k < l) return [i,j,k,l];
      if (j < l) return [i,j,l,k];
      if (i < l) return [i,l,j,k];
      return [l,i,j,k];
    } else if (i < k) {
      if (j < l) return [i,k,j,l];
      if (k < l) return [i,k,l,j];
      if (i < l) return [i,l,k,j];
      return [l,i,k,j];
    } else {
      if (j < l) return [k,i,j,l];
      if (i < l) return [k,i,l,j];
      if (k < l) return [k,l,i,j];
      return [l,k,i,j];
    }
  } else {
    if (i < k) {
      if (k < l) return [j,i,k,l];
      if (i < l) return [j,i,l,k];
      if (j < l) return [j,l,i,k];
      return [l,j,i,k];
    } else if (j < k) {
      if (i < l) return [j,k,i,l];
      if (k < l) return [j,k,l,i];
      if (j < l) return [j,l,k,i];
      return [l,j,k,i];
    } else {
      if (i < l) return [k,j,i,l];
      if (j < l) return [k,j,l,i];
      if (k < l) return [k,l,j,i];
      return [l,k,j,i];
    }
  }
}

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

Ответ 5

Для такого небольшого набора данных вы хотите как можно более простой алгоритм. Скорее всего, базовая Вставка Сортировка будет делать так же, как вы могли бы хотеть.

Нужно будет узнать больше о системе, на которой это работает, сколько раз вам нужно сделать этот сорт второй и т.д.... но общее правило в небольших классах - это упростить его. Quicksort и т.п. не выгодны.

Ответ 6

Сортировочные сети могут быть легко реализованы в SIMD, хотя он начинает становиться уродливым вокруг N = 16. Для N = 4 или N = 8, хотя это было бы хорошим выбором. В идеале вам нужно много небольших наборов данных для сортировки одновременно, т.е. Если вы сортируете 8-битные значения, тогда вы хотите, чтобы по меньшей мере 16 наборов данных сортировались - гораздо сложнее делать такие вещи в векторах SIMD.

Смотрите также: Самый быстрый тип фиксированной длины 6 int array