Поскольку пузырьковая сортировка имеет довольно плохие свойства локальности памяти, я думаю, что ваши реализации ограничены пропускной способностью памяти, хотя я не проводил никакого тестирования.
Собственный Haskell String = [Char]
чрезвычайно удобен, но не подходит, когда производительность является основным приоритетом. Я забыл точные цифры, но я уверен, что String
использует не менее 16 байтов на символ в 32-битной системе и примерно вдвое больше, чем в 64-битной системе. В отличие от этого я предполагаю, что ваша программа на C использует 1 байт на символ. Таким образом, от одного этого можно ожидать примерно 16-кратного замедления.
Вы также эмулируете изменяемый массив с помощью пары связанных списков (это обычно называется "молнией"). Это достаточно эффективно, если вы делаете локальные модификации вокруг движущегося фокуса, что верно по большей части в пузырьковой сортировке. Однако в конце каждого прохода вам необходимо переместить фокус обратно на начало (это rev
). Это, вероятно, учитывает еще один фактор 2 в объеме работы, проделанной в алгоритме.
Итак, я не думаю, что ваши тесты очень удивительны.
Если вы хотите написать быструю пузырьковую сортировку в Haskell, вы можете реализовать псевдокод непосредственно в монаде ST
, используя изменяемый распакованный массив. Я не думаю, что вы увидите пузырчатую сортировку на совершенно чистом языке с гораздо лучшим постоянным коэффициентом в ближайшее время (хотя я бы, конечно, хотел бы оказаться неправым).