I was working on implementing a quicksort yesterday, and then I ran it, expecting a faster runtime than the Mergesort (which I had also implemented). I ran the two, and while th
I think as long as data fits in memory, good merge sort implementation performs better than good quick sort implementation.
One of the most widely used implementations of qsort(), glibc qsort(), internally uses merge sort for most of the cases when data fits in memory. This merge sort allocates a temporary memory space used for merging, which adds some memory overhead, but most of the time, it outperforms its own internal quicksort implementation with good pivot selection and optimization. glibc only uses quicksort when the data and the temporary memory for merge sort cannot fit in memory.
I have measured performance of those two implementation on my machine with 2.1GHz CPU with several GB of RAM. The inputs are generated with pseudo-random generator, and each key is 32bit unsigned integer, which means a bit of more comparison cycles than integer comparison due to interface of comparison function.
For merge sort:
2 MB, time_diff 165.156000 ms, 78.752518 ns per byte
4 MB, time_diff 344.298000 ms, 82.087040 ns per byte
8 MB, time_diff 730.926000 ms, 87.133169 ns per byte
16 MB, time_diff 1541.215000 ms, 91.863573 ns per byte
32 MB, time_diff 3088.924000 ms, 92.057109 ns per byte
64 MB, time_diff 6262.868000 ms, 93.324006 ns per byte
128 MB, time_diff 12887.018000 ms, 96.015766 ns per byte
256 MB, time_diff 26731.597000 ms, 99.582959 ns per byte
For quick sort:
2 MB, time_diff 243.519000 ms, 116.118908 ns per byte
4 MB, time_diff 504.975000 ms, 120.395422 ns per byte
8 MB, time_diff 1075.276000 ms, 128.182888 ns per byte
16 MB, time_diff 2183.865000 ms, 130.168498 ns per byte
32 MB, time_diff 4343.993000 ms, 129.461080 ns per byte
64 MB, time_diff 8714.166000 ms, 129.851192 ns per byte
128 MB, time_diff 17881.344000 ms, 133.226395 ns per byte
256 MB, time_diff 36751.029000 ms, 136.908252 ns per byte
You can see that there are clear differences in performance between those two implementation and why mergesort is preferred over quicksort in such widely used qsort implementation. The main reason behind this difference seems to be because quick sort has 10-20% more comparisons than merge sort, due to uneven splitting at each step.