Recently, I did some study on sorting algorithms and I’m amazed to find that the sort from standard Java Runtime Environment (JRE) is NOT as efficient as I expected. According to Java-DOC’s description:
public static <T> void sort(T[] a, Comparator<? super T> c)
Sorts the specified array of objects according to the order induced by the specified comparator. All elements in the array must be mutually comparable by the specified comparator (that is, c.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the array).
This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.
Implementation note: This implementation is a stable, adaptive, iterative mergesort that requires far fewer than n lg(n) comparisons when the input array is partially sorted, while offering the performance of a traditional mergesort when the input array is randomly ordered. If the input array is nearly sorted, the implementation requires approximately n comparisons. Temporary storage requirements vary from a small constant for nearly sorted input arrays to n/2 object references for randomly ordered input arrays.
The implementation takes equal advantage of ascending and descending order in its input array, and can take advantage of ascending and descending order in different parts of the the same input array. It is well-suited to merging two or more sorted arrays: simply concatenate the arrays and sort the resulting array.
The implementation was adapted from Tim Peters’s list sort for Python ( TimSort). It uses techniques from Peter McIlroy’s “Optimistic Sorting and Information Theoretic Complexity”, in Proceedings of the Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, January 1993.
I have checked another sort method’s description:
Implementation note: The sorting algorithm is a Dual-Pivot Quicksort by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm offers O(n log(n)) performance on many data sets that cause other quicksorts to degrade to quadratic performance, and is typically faster than traditional (one-pivot) Quicksort implementations.
So I’m curious to know how good the built-in sort is and whether my home-made sort can defeat it. It sounds like playing with AlphaGo, but I still decide to have a go. For the completeness, I include elementary sorting methods e.g. select sort, insert sort and shell sort, which have the performance of,
as well as more advanced sort e.g. merge sort and quick sort with the performance of.
Here is the detailed source code.
Select sort
1 | Comparable[] selectSort(Comparable[] t) { |
Insert sort
1 | Comparable[] insertSort(Comparable[] t) { |
Shell sort
1 | Comparable[] shellSort(Comparable[] t) { |
Heap sort
Heap sort relies on Priority Queue, which itself is not a straightforward and therefore increase the overheads of resource consumption during sorting. It makes it the least competitive among all advanced sorting methods. For the brevity, I won’t post the full source code of Priority Queue:
1 | public class PriorityQueue { |
Merge sort
1 | Comparable[] mergeSort(Comparable[] t) { |
Quick sort
1 | Comparable[] quickSort(Comparable[] t) { |
Performance & Conclusion
These are typical implementations without many well-known optimizations. The goal is to keep the code short and easy to understand. Let’s put them into use to see if they are competitive with JRE’s built-in sort.

Y-axis is millisecond, X-axis is the size of array to be sorted.
For each round, the performance is measured by generating 10 test data and sort these random data with different methods and take the mean time. The test data is shuffled in this way:1
2
3
4
5void shuffle(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
exchange(a, i, random(0, i));
}
}
From the chart we can see that all elementary sort methods start to struggle with the performance for arrays of 20K (an one-second waiting time is an obvious delay for user experience as well as a cross boundary transaction), while those advanced sort methods’ limits are around 2,000K.
Admittedly, modern compiler and CPU are competitive enough for even elementary sort methods to handle array within 10K. In terms of code complexity and footprint, both Select Sort and Insert Sort have a straightforward code structure and easy to read, so they can be good candidates for non-resource-critical use. Shell Sort, however, has a rather complicated code and has the most significant performance issue and therefore should not be used unless in the special circumstance that most adjacent elements have a far distance.
On the other hand, for large-scale applications, a decent sort method like Merge Sort or Quick Sort is the only choice when the sorting array consists of more than millions of data. Among these methods, Heap Sort has the least performance, Merge Sort falls behind when the data is over one million and Quick Sort manages to finish the sorting of one million within half a second.
Another interesting finding is although the benchmark of JRE’s built-in sort is stable for different inputs, it is beaten by my home-made Quick Sort when the size of incoming array is over one million. I did the same test several times and each time had the same conclusion.