Morwenn / cpp-sort

Sorting algorithms & related tools for C++14
MIT License
617 stars 57 forks source link

The random-access version of quick_merge_sort runs in O(n²) #179

Closed Morwenn closed 3 years ago

Morwenn commented 3 years ago

I ran a quicksort killer like the one described in #178 with the following algorithms from the library - the ones that have a quicksort-like structure:

Here are the results:

Benchmark of the number of comparisons performed against a quicksort killer input

It is quite easy to see the difference between the O(n log n) and the O(n²) algorithms there. And it clearly shows that the random-access version of quick_merge_sort runs in O(n²). The culprit is the random-access nth_element, which also means that the libc++ implementation of std::nth_element is quadratic.

Morwenn commented 3 years ago

I tried to change the implementation of nth_element for random-access iterators to miniselect's implementation of Andrei Alexandrescu's QuickselectAdaptive selection algorithm. It is very slightly slower than the libc++ algorithm on average, but correctly handles the killer input without going quadratic:

Benchmark of the number of comparisons performed against a quicksort killer input

Next step is to steal the miniselect implementation and adapt it as needed.

Morwenn commented 2 years ago

Related: llvm/llvm-project#52747