¿Por qué Java no usa una clasificación de radix en primitivas?

12

java.util.Arrays.sort(/* int[], char[], short[], byte[], boolean[] */) se implementa como un 'ordenamiento rápido sintonizado' en lugar de una clasificación de radix.

Hice una comparación de velocidad hace un tiempo, y con algo como n> 10000, la clasificación de radix siempre fue más rápida. ¿por qué?

Jakob Weisblat
fuente

Respuestas:

17

Yo especularía que:

  • Array.sort se implementa como quicksort, porque quicksort puede ordenar cualquier cosa en un tiempo decente dado un comparador.
  • Ordenar una lista de 10000 entradas no es tan común. Acceder a una estructura de datos de 10000 o más elementos es bastante común. Si necesita mantener el orden, un árbol de búsqueda equilibrado suele ser una mejor manera de hacerlo que ordenar su matriz completa cada vez que necesita el elemento más pequeño.
  • Ordenar primitivas no es tan común, a pesar de lo que la universidad pueda enseñar.

El punto es que no es un caso de uso tan común, que su optimización debe estar en la biblioteca estándar. Si ha escrito una aplicación, que tiene problemas de rendimiento, donde determina a través de la elaboración de perfiles que ordenar una matriz de más de 10000 ints es realmente el cuello de botella, entonces también podría escribir la clasificación a mano o reconsiderar su elección de estructura de datos en el primer sitio.

back2dos
fuente
No estoy 100% seguro, pero creo que TimSort se usa en algunos casos ahora.
Martijn Verburg
1
Pero no hay algo como Array.sort, hay varios Array.sorts, y la pregunta era sobre esto especializado para los tipos numéricos.
Danubian Sailor
6

Back2dos lo ha dicho todo, solo intentaré aclarar más el punto que creo que es el más importante:

La clasificación por radix solo puede ordenar los valores primitivos reales que están contenidos dentro de la matriz, en función de sus patrones de dígitos binarios. En escenarios reales de ingeniería de software del mundo real, este caso casi nunca se encuentra . Lo que solemos hacer con mucha más frecuencia es ordenar matrices de estructuras de datos más complejas (no primitivas), y algunas veces clasificamos matrices de índices a otras entidades.

Ahora, una matriz de índices para otras entidades es de hecho una matriz de primitivas, pero el orden de clasificación es proporcionado por la interfaz del comparador (y / o delegado en C #) que compara no los índices, sino las entidades indexadas por los índices. Por lo tanto, el orden de clasificación no tiene absolutamente ninguna relación con el orden de los valores de las primitivas y, por lo tanto, la clasificación por radix es absolutamente inútil para este escenario.

Un ejemplo:

Tenemos una serie de cadenas: [0] = "Mike", [1] = "Albert", [2] = "Zoro". Luego declaramos una matriz de índices para esas cadenas: [0] = 0, [1] = 1, [2] = 2. Luego, clasificamos la matriz de índices, pasándole un comparador que no compara los índices en sí, sino las cadenas reales a las que se refieren estos índices. Después de ordenar, la matriz resultante de índices se verá así: [0] = 1, [1] = 0, [2] = 2. Como puede ver, este orden no tiene nada que ver con los patrones binarios de los valores contenidos en la matriz, y sin embargo, al atravesar esta matriz de índices y obtener cada cadena correspondiente, visitamos las cadenas en orden ordenado.

Mike Nakis
fuente