2011-10-14 26 views
38

¿Por qué escucho sobre quicksort ser el algoritmo de clasificación global más rápido cuando timsort (de acuerdo con la wikipedia) parece funcionar mucho mejor? Google no pareció mostrar ningún tipo de comparación.Comparación entre timsort y quicksort

+0

Con un poco más de reflexión y algunas referencias, esta podría ser una buena pregunta. –

+19

Porque las personas eligen ignorar esa oferta rápida es O (n^2) el peor de los casos. – Patrick87

+3

Una respuesta posible sería: Hable con las personas equivocadas. Pero como otra respuesta ya implícita: qsort es mucho más antiguo, por lo que se usa en muchas más bibliotecas, y usted sabe: nunca toque un sistema en ejecución. Si el tiempo promedio de ejecución (es decir: en los casos de uso de las personas que lo usan) no es mucho peor que el tiempo de ejecución de un algoritmo diferente (como timsort) las personas son demasiado vagas (o tienen mejores cosas que hacer) que cambiar algo, que hace lo mismo al mismo tiempo. Y en algunas aplicaciones (parece, por ejemplo, python), timsort ya está predeterminado. – flolo

Respuesta

22

TimSort es un mergesort altamente optimizado, es estable y más rápido que el viejo mergesort.

cuando se comparan con quicksort, tiene dos ventajas:

  1. Es increíblemente rápido para la secuencia de datos casi ordenada (incluyendo inversa ordenadas de datos);
  2. El peor de los casos sigue siendo O (N * LOG (N)).

Para ser sincero, no creo que el n. ° 1 sea una ventaja, pero sí me impresionó.

Estas son las ventajas de QuickSort

  1. QuickSort es muy muy simple, incluso una aplicación altamente sintonizado, podemos escribir sus códigos pseduo dentro de 20 líneas;
  2. QuickSort es el más rápido en la mayoría de los casos;
  3. El consumo de memoria es LOG (N).

Actualmente, Java 7 SDK implementa timsort y una nueva variante de quicksort: es decir, Dual Pivot QuickSort.

Si necesita una clasificación estable, intente con timsort, de lo contrario, comience con la ruta rápida.

+1

# 1 * puede * ser una gran ventaja. Si mantiene una lista de datos que debe volver a ordenar con frecuencia (porque los elementos se insertan, anexan o modifican), tener un algoritmo que le permita reordenar esos datos a un precio muy económico es extremadamente útil. Si es útil depende de la situación, de seguro, pero es enorme en algunos casos y también se siente obvio: las listas casi ordenadas no deberían ser difíciles de clasificar. –

+1

@JeremyWest: si sabe que los datos ya están ordenados, debe usar la búsqueda binaria para insertar nuevos valores. No lo clasifique una y otra vez. –

+1

@EricDuminil La búsqueda binaria es rápida, pero las inserciones en el medio de una matriz no lo son. Hay muchas aplicaciones en las que la solución más simple (y con frecuencia la más eficiente) es reordenar una lista ordenada en su mayoría cuando se necesita ordenarla, pero dejarla sin clasificar de otro modo. O casos en los que lee datos que están principalmente ordenados y luego necesita ordenarlos. No estoy sugiriendo que esta sea * siempre * la mejor solución, pero a veces lo es. Y es una de las razones por las que los tipos que funcionan bien en listas mayormente ordenadas son preferibles, particularmente para bibliotecas estándar. –

20

Más o menos, tiene que ver con el hecho de que Timsort es un algoritmo de clasificación híbrido. Esto significa que, si bien los dos tipos subyacentes que utiliza (clasificación Mergesort e Insertion) son peores que Quicksort para muchos tipos de datos, Timsort solo los usa cuando es ventajoso hacerlo.

En un nivel un poco más profundo, como Patrick87 estados, quicksort es el peor de los casos O (n) algoritmo. La elección de un buen pivote no es hard, pero garantizar una orden rápida O (n log n) tiene como resultado una clasificación generalmente más lenta en promedio.

Para obtener más información sobre Timsort, consulte this answer y la publicación de blog vinculada. Básicamente, asume que la mayoría de los datos ya están parcialmente ordenados, y construye "corridas" de datos ordenados que permiten fusiones eficientes utilizando mergesort.

10

En general, quicksort es el mejor algoritmo para matriz primitiva. Esto se debe a la localidad de memoria y al caché.

JDK7 usa TimSort para matriz de objetos. La matriz de objetos solo contiene la referencia del objeto. El objeto en sí se almacena en Heap. Para comparar el objeto, necesitamos leer el objeto del montón. Esto es como leer de una parte del montón para un objeto, luego leer al azar el objeto de otra parte del montón. Habrá una gran cantidad de errores de caché. Supongo que por esta razón la localidad de memoria ya no es importante. Esta puede ser la razón por la cual JDK solo utiliza TimSort para matriz de objetos en lugar de matriz primitiva.

Esto es solo mi suposición.

1

Aquí hay números de referencia de mi máquina (i7-6700 CPU, 3.4GHz, Ubuntu 16.04, gcc 5.4.0, los parámetros: SIZE = 100000 y corre = 3):

$ ./demo 
Running tests 
stdlib qsort time:     12246.33 us per iteration 
##quick sort time:     5822.00 us per iteration 
merge sort time:     8244.33 us per iteration 
...  
##tim sort time:     7695.33 us per iteration 
in-place merge sort time:   6788.00 us per iteration  
sqrt sort time:      7289.33 us per iteration  
... 
grail sort dyn buffer sort time: 7856.67 us per iteration 

El punto de referencia proviene de proyecto de Swenson sort en la que tal como se aplica varios algoritmos de ordenación en C. Presumiblemente, sus implementaciones son lo suficientemente buenas para ser representativa , pero no los he investigado

Así que realmente no se puede decir. Los números de referencia solo son relevantes durante un máximo de dos años y luego debe repetirlos. Posiblemente, timsort venció qsort waaay en 2011 cuando se formuló la pregunta, pero los tiempos han cambiado. O qsort siempre fue el más rápido, pero timsort lo superó con datos no aleatorios. O el código de Swenson no es tan bueno y un programador mejor cambiaría la tendencia a favor de timsort. O tal vez yo aspire y no usé el CFLAGS correcto al compilar el código. O ... Entiendes el punto.