Quicksort optimizations

空扰寡人 提交于 2019-12-03 17:16:45

You have a bug in the algorithm itself. E.g. there is undefined behaviour here:

The insertion sort potentially reads out-of-bounds in the marked following line:

*(hole--) = *(hole-1);

It reads before the first element. I suggest you meant

*hole = *(hole-1);
--hole;

Update quickly benchmarked with GNU g++ 4.6.1 on 64bit linux. I rearranged the timing to be at totals, so I didn't have to reimplement the clock functions (I'm lazy).

Adapted code: http://ideone.com/LgAgs

Built with

g++ -std=c++0x -g -O3 test.cpp -o test

Here's the result: The insertion sort appears to be roughly ~60-100x slower than the others.

START Testing: insertion_sort. With --- 8 elements.
START Testing: insertion_sort. With --- 16 elements.
START Testing: insertion_sort. With --- 32 elements.
START Testing: insertion_sort. With --- 64 elements.
START Testing: insertion_sort. With --- 128 elements.
START Testing: insertion_sort. With --- 256 elements.
START Testing: insertion_sort. With --- 512 elements.
START Testing: insertion_sort. With --- 1024 elements.
START Testing: insertion_sort. With --- 2048 elements.
START Testing: insertion_sort. With --- 4096 elements.
START Testing: insertion_sort. With --- 8192 elements.
START Testing: insertion_sort. With --- 16384 elements.
START Testing: insertion_sort. With --- 32768 elements.
START Testing: insertion_sort. With --- 65536 elements.

real    0m1.532s
user    0m1.524s
sys 0m0.004s
START Testing: quicksort. With --- 8 elements.
START Testing: quicksort. With --- 16 elements.
START Testing: quicksort. With --- 32 elements.
START Testing: quicksort. With --- 64 elements.
START Testing: quicksort. With --- 128 elements.
START Testing: quicksort. With --- 256 elements.
START Testing: quicksort. With --- 512 elements.
START Testing: quicksort. With --- 1024 elements.
START Testing: quicksort. With --- 2048 elements.
START Testing: quicksort. With --- 4096 elements.
START Testing: quicksort. With --- 8192 elements.
START Testing: quicksort. With --- 16384 elements.
START Testing: quicksort. With --- 32768 elements.
START Testing: quicksort. With --- 65536 elements.

real    0m0.025s
user    0m0.016s
sys 0m0.008s
START Testing: mixed_quicksort. With --- 8 elements.
START Testing: mixed_quicksort. With --- 16 elements.
START Testing: mixed_quicksort. With --- 32 elements.
START Testing: mixed_quicksort. With --- 64 elements.
START Testing: mixed_quicksort. With --- 128 elements.
START Testing: mixed_quicksort. With --- 256 elements.
START Testing: mixed_quicksort. With --- 512 elements.
START Testing: mixed_quicksort. With --- 1024 elements.
START Testing: mixed_quicksort. With --- 2048 elements.
START Testing: mixed_quicksort. With --- 4096 elements.
START Testing: mixed_quicksort. With --- 8192 elements.
START Testing: mixed_quicksort. With --- 16384 elements.
START Testing: mixed_quicksort. With --- 32768 elements.
START Testing: mixed_quicksort. With --- 65536 elements.

real    0m0.016s
user    0m0.004s
sys 0m0.008s

So finally I think I figured out at least a part of what's wrong.

Thanks to sehe for the hint.

  • When compiled with -O3 (on GCC, or /Ox on MSVC) mixed_inplace is the fastest and pretty close to std::sort()
    • I suppose this means that at least some of the expected optimizations (tail-recursion) weren't applied by compiler when compiling at lower optimization level.
  • Build should be release build (w/o -g on GCC).
  • @sehe: insertion sort performance is irrelevant.
  • std::sort() implementation on GCC and MSVC are different, so it's not really right to compare the two.

Here are the results on windows and linux with and w/o optimization options:

Windows with MSVC:

Windows with GCC:

RedHat Linux with GCC:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!