4.6 Empirical comparison of sorting algorithms
Which sorting algorithm is fastest? Asymptotic complexity analysis lets us distinguish between and algorithms, but it does not help distinguish between algorithms with the same asymptotic complexity. Nor does asymptotic analysis say anything about which algorithm is best for sorting small lists. For answers to these questions, we can turn to empirical testing.
Sort | 1K | 10K | 100K | 1M | 10M | 100K sorted | 100K reversed |
---|---|---|---|---|---|---|---|
Insertion sort | 0.009 | 0.88 | 82 | — | — | 0.003 | 175 |
Bubble sort | 0.020 | 2.08 | 211 | — | — | 97 | 280 |
Selection sort | 0.006 | 0.68 | 68 | — | — | 66 | 66 |
Mergesort | 0.001 | 0.009 | 0.105 | 1.26 | 17.4 | 0.084 | 0.087 |
Merge (cutoff 20) | 0.000 | 0.006 | 0.077 | 1.00 | 15.1 | 0.048 | 0.071 |
Quicksort | 0.000 | 0.006 | 0.074 | 0.95 | 12.6 | 0.045 | 0.047 |
Quick (cutoff 20) | 0.000 | 0.005 | 0.066 | 0.87 | 11.8 | 0.030 | 0.032 |
Sort | 4K | 40K | 400K | 4M | 40M | 400K sorted | 400K reversed |
---|---|---|---|---|---|---|---|
Insertion sort | 0.015 | 0.62 | 69 | — | — | 0.01 | 126 |
Bubble sort | 0.018 | 1.46 | 312 | — | — | 35 | 175 |
Selection sort | 0.023 | 0.96 | 112 | — | — | 41 | 79 |
Mergesort | 0.001 | 0.010 | 0.14 | 1.06 | 13.2 | 0.11 | 0.12 |
Merge (cutoff 20) | 0.001 | 0.009 | 0.12 | 1.03 | 12.3 | 0.10 | 0.10 |
Quicksort | 0.001 | 0.008 | 0.06 | 0.66 | 8.2 | 0.04 | 0.03 |
Quick (cutoff 20) | 0.001 | 0.007 | 0.06 | 0.57 | 8.0 | 0.04 | 0.04 |
Tables 4.1, 4.2 above show timing results for actual implementations of the sorting algorithms presented in this chapter. The algorithms compared include Insertion sort (Section 3.6), Bubble sort (Section 3.4), Selection sort (Section 3.5), Quicksort (Section 4.4), and Mergesort (Section 4.2).
For Quicksort and Mergesort, two versions are compared: the basic implementation, and an optimised version that falls back to Insertion sort for sublists of length below 20.
The various sorting algorithms are shown for random integer arrays of sizes being multiples of 10. The final two columns of each table show the performance for the algorithms on inputs of size 100,000 (400,000 for the Java tests) where the numbers are in ascending (sorted) and descending (reverse sorted) order, respectively. These columns demonstrate best-case performance for some algorithms and worst-case performance for others. They also show that for some algorithms, the order of input has little effect.
These figures show a number of interesting results. As expected, the sorts are quite poor performers for large arrays. Insertion sort and Selection sort outperforms Bubble sort in all cases. We also see that Insertion sort is the fastest algorithm of all if the input is already sorted. Quicksort with a cutoff to Insertion sort is clearly the best overall algorithm, but recall that this experiment was only run on random integer arrays. In general, optimising the various algorithms makes a noticeable improvement for larger array sizes.