2

java.util.Arrays uses quicksort (actually dual pivot quicksort in the most recent version) for primitive types such as int and mergesort for objects that implement Comparable or use a Comparator. Why the difference? Why not pick one and use it for all cases?

Paul S
  • 81
  • 2
  • 13

2 Answers2

3

A good explanation here:-

Quicksort is faster in both cases. Mergesort is stable in both cases. But for primitive types quicksort is stable too! That’s because primitive types in Java are like elementary particles in quantum mechanics. You can’t tell the difference between one 7 and another 7. Their value is all that defines them. Sort the array such [7, 6, 6, 7, 6, 5, 4, 6, 0] into [0, 4, 5, 6, 6, 6, 6, 7, 7]. Not only do you not care which 6 ended up in which position. It’s a meaningless question. The array positions don’t hold pointers to the objects. They hold the actual values of the objects. We might as well say that all the original values were thrown away and replaced with new ones. Or not. It just doesn’t matter at all. There is no possible way you can tell the difference between the output of a stable and unstable sorting algorithm when all that’s sorted are primitive types. Stability is irrelevant with primitive types in Java.

Ross Drew
  • 8,163
  • 2
  • 41
  • 53
  • Merge sort performs more moves but fewer compares than quick sort. If the compare overhead is sufficiently greater than move overhead, then merge sort is faster. For a processor with 16 general purpose register, like X86 / X64 in 64 bit mode, a 4 way merge sort is as fast as quick sort, but I doubt Java uses a 4 way merge sort. – rcgldr Nov 09 '15 at 14:41
0

I think that the reason is stability.

The primitives do not have an identity, so it is impossible to distinguish between 2 integers with the same value. This is not the case for referenced types this might be problematic as quick sort might change their relative positions and that is why a more stable merge sort is used.

Also, not using n*log n for primitives might be because it would require a clone of an array. For reference types it does not really matter as they arrays of objects are normally bigger than the corresponding arrays of references. However, for primitives clonning uses double memory.

aviad
  • 8,229
  • 9
  • 50
  • 98