¿La forma más rápida de eliminar duplicados en una gran lista de palabras?


14

Necesito deduplicar una gran lista de palabras. Probé varios comandos e hice algunas investigaciones aquí y aquí donde explican que la forma más rápida de deduplicar una lista de palabras parece estar usando awk.

awk -> O (n)? ordenar -> O (n log n)?

Sin embargo, descubrí que esto no parece ser cierto. Aquí están mis resultados de prueba:

sort -u input.txt -o output.txt 


usuario real 0m12.446s 0m11.347s
sys 0m0.906s

awk '!x[$0]++' input.txt > output.txt


usuario real 0m47.221s 0m45.419s
sys 0m1.260s

Entonces usar sort -u es 3.7 veces más rápido. ¿Por qué es esto? ¿Existe un método aún más rápido para hacer deduplicación?

*********** Actualizar ********

Como alguien señaló en los comentarios, podría ser que mi lista de palabras ya estuviera ordenada hasta cierto punto. Para excluir esta posibilidad, generé dos listas de palabras usando este script de Python .

Lista1 = 7 Mb
Lista2 = 690 Mb

Resultados AWK:
List1
real 0m1.643s
usuario 0m1.565s
sys 0m0.062s

List2 usuario
real 2m6.918s
2m4.499s
sys 0m1.345s

Resultados Ordenar:
Lista1
reales 0m0.724s
0m0.666s usuario
sys 0m0.048s

List2
real 1m27.254s
usuario 1m25.013s
sys 0m1.251s


¿Podría ser que sus datos de entrada ya estén ordenados?
iruvar


2
La notación Big O se trata de lo que sucede cuando la longitud de entrada se aproxima al infinito: le dice que un algoritmo escala con una gran entrada. Algunos algoritmos funcionan mejor con un tamaño de entrada pequeño.
ctrl-alt-delor

1
Karlpy, ¿en qué orden ejecutó, awk primero u ordenado? Eso puede marcar la diferencia debido al almacenamiento en caché de archivos
iruvar

1
@karlpy: "Cambié el nombre del archivo ..." Si quiere decir que cambió el nombre del archivo, eso no es suficiente. Cambiar el nombre de un archivo solo asocia un nuevo nombre con el inodo anterior, que todavía apunta a los mismos bloques de datos antiguos. Si fueron almacenados en caché, todavía están almacenados en caché. ISTM dice que una técnica mucho mejor sería (1) hacer una copia del archivo y luego (2) ejecutar un comando en un archivo y (3) ejecutar el otro comando en el otro archivo.
Scott

Respuestas:


3

Está haciendo la pregunta incorrecta, o la pregunta es incorrecta y en la pila incorrecta, esta es una mejor pregunta en la programación / desbordamiento de pila para que las personas le den respuestas basadas en los algoritmos utilizados dentro de awk y sort.

PD: también haga lo necesario con nawk, mawk y gawk para darnos más detalles sobre "zona";) y realice las corridas como 100 veces cada una con la desviación mínima, máxima, promedio y estándar.

En cualquier caso, volviendo a la pregunta en cuestión, de CompSci 210, se trata de los algoritmos utilizados. La clasificación hace uso de varias, dependiendo de los tamaños y las restricciones de memoria a las que se enfrenta para guardar archivos en el disco en archivos temporales que se combinarán una vez que se quede sin memoria, y tendrá que buscar en el código fuente para ver qué el comando sort (1) específico utiliza en el sistema operativo específico en el que lo está ejecutando, pero por experiencia se está cargando en la memoria todo lo que puede, realice una clasificación rápida, escriba en el disco, repita el enjuague y, en el momento Al final, hará una especie de fusión de los pequeños archivos ordenados. Entonces aquí tendrá el O (n * log2 (N)) para las partes, y luego una operación aproximada de fusión O (n * log (n))

awk: El mecanismo x [$ 0] ++ es "suponga" que use hashing. PERO el problema con el hash, una supuesta operación de "búsqueda" de O (1), son las colisiones y el manejo de las colisiones. Esto podría causar un problema cuando los datos no están bien distribuidos, ni llenando los cubos, etc. y en listas grandes, el hash podría ser un gran problema de memoria si el manejo de las colisiones no se realiza correctamente (y es posible que necesite ajuste los algoritmos de hash para los datos esperados), y luego debe observar el rendimiento de las funciones de hashing reales y luego el O (1) podría estar más cerca de un O (log (n)) para los insertos (Ie. O (1) para la primera búsqueda, y si NO existe, se agrega lo que podría ser O (log (n))), y luego el n * O (1) se convierte en * O (log (n)) = > O (n * log (n)), sin mencionar que también está haciendo las cosas de manera "interpretada" :)


-2

La diferencia de velocidad se debe a que 'sort' es un comando ( enlace ), mientras que 'awk' es un lenguaje de programación ( enlace ).

El comando 'sort' toma entrada y devuelve salida. Mientras que 'awk' es un lenguaje de programación, que primero interpreta el código (comando de terminal) y luego comienza a procesarlo. Simple como eso.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.