¿Cómo explica la localidad de caché el hecho de que la ordenación rápida suele ser más rápida que la ordenación por fusión?

P: ¿Cómo explica la localidad de caché el hecho de que la ordenación rápida suele ser más rápida que la ordenación por fusión?

Mi autoridad para responder a esta pregunta proviene de los experimentos que hice en tiempos de ejecución como parte de mi libro, Optimized C ++ . Recomiendo realizar experimentos antes de hacer afirmaciones sobre el rendimiento.

A1: ¿Qué te hace pensar que quicksort es más rápido que el tipo de fusión? Mi observación de la biblioteca estándar de C ++ ordena std :: sort (), que generalmente se implementa como quicksort, y std :: stable_sort (), que es un tipo de combinación, reveló que std :: stable_sort () es más rápido cuando ambos se realizan sobre una matriz.

A2: Quicksort, como se suele demostrar a los estudiantes universitarios de CS, se implementa sobre una matriz, mientras que la ordenación por fusión se implementa sobre una estructura de datos vinculada. Cuando se compara de esta manera, std :: sort () en una matriz fue aproximadamente un 25% más rápido que list :: sort () en los mismos datos, que es una combinación de clasificación en una estructura de datos vinculada.

Las estructuras de datos vinculados están, por naturaleza, dispersas en la memoria, mientras que los elementos de la matriz están muy juntos. Un desarrollador con mentalidad de rendimiento puede sospechar de la fusión cuando se implementa sobre una estructura de datos vinculada, pero el comportamiento real de la memoria caché puede ser difícil de predecir a partir de una regla general informal como esta.

Quicksort naturalmente explota la localidad de caché porque opera en sub matrices contiguas cortas durante la mayor parte de su tiempo de ejecución.

Por el contrario, mergeseort y muchos otros, como heapsort, realizan lecturas dispersas que no se pueden conocer de antemano y también desperdician el resto de la línea de caché alrededor del valor que realmente necesitan.

Verá, la memoria de acceso aleatorio es un poco inapropiado. Mientras que DRAM tiene casi la misma latencia para cualquier dirección arbitraria, la jerarquía de caché no. Es más eficiente mantener los accesos en un espacio de direcciones pequeño con respecto al tiempo, que es un subconjunto de un espacio de direcciones más grande y así sucesivamente para todos los niveles de caché. Quicksort probablemente usa muchos más niveles de pila que los niveles de caché, pero los explota perfectamente.