¿Por qué la utilidad wc es tan lenta?
Cuando lo ejecuto en un archivo grande, tarda aproximadamente 20 veces más que md5sum:
MyDesktop:/tmp$ dd if=/dev/zero bs=1024k count=1024 of=/tmp/bigfile
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.687094 s, 1.6 GB/s
MyDesktop:/tmp$ time wc /tmp/bigfile
0 0 1073741824 /tmp/bigfile
real 0m45.969s
user 0m45.424s
sys 0m0.424s
MyDesktop:/tmp$ time md5sum /tmp/bigfile
cd573cfaace07e7949bc0c46028904ff /tmp/bigfile
real 0m2.520s
user 0m2.196s
sys 0m0.316s
No es solo una extraña condición de borde causada por el archivo lleno de nulos, veo la misma diferencia en el rendimiento incluso si el archivo está lleno de datos aleatorios o es un archivo de texto.
(Esto está en Ubuntu 13.04, 64 bit)
performance
wc
Johnny
fuente
fuente
Respuestas:
Así que fui a la fuente, y parece que la lentitud está en el manejo de caracteres de doble byte. Esencialmente, para cada carácter leído, debe llamar
mbrtowc()
para intentar convertirlo en un carácter ancho, luego se prueba ese carácter ancho para ver si es un separador de palabras, un separador de línea, etc.De hecho, si cambio mi
LANG
variable de configuración regional por defectoen_US.UTF-8
(UTF-8 es un conjunto de caracteres multibyte) y lo configuro en "C
" (conjunto de caracteres de un solo byte simple),wc
puedo usar optimizaciones de un solo byte, lo que lo acelera considerablemente, tomando solo alrededor de un cuarto del tiempo que antes.Además, solo tiene que verificar cada carácter si está haciendo recuentos de palabras (
-w
), longitud de línea (-L
) o caracteres (-m
). Si solo está haciendo recuentos de bytes y / o líneas, puede omitir el manejo de caracteres anchos y luego se ejecuta extremadamente rápido, más rápido quemd5sum
.Lo pasé por
gprof
, y las funciones que se utilizan para manejar los caracteres de varios bytes (mymbsinit()
,mymbrtowc()
,myiswprint()
, etc.) están ocupando aproximadamente el 30% del tiempo de ejecución solo, y el código que los pasos a través de la memoria intermedia es mucho más compleja porque tiene que maneja pasos de tamaño variable a través del búfer para caracteres de tamaño variable, así como rellena los caracteres parcialmente completados que abarcan el búfer de regreso al comienzo del búfer para que pueda manejarse la próxima vez.Ahora que sé qué buscar, encontré algunas publicaciones que mencionan la lentitud utf-8 con algunas utilidades:
/programming/13913014/grepping-a-huge-file-80gb-any-way-to-speed-it-up http://dtrace.org/blogs/brendan/2011/12/08 / 2000x-performance-win /
fuente
md5sum
¡nunca le permitirá contar el número de palabra ywc
no calculará el hash md5 del archivo! Es como preguntar por qué mi auto es tan lento en comparación con mi máquina de escribir cuando escribo un texto.wc
de hecho, está vinculada a la CPU cuando se procesan caracteres de varios bytes.Solo una suposición, pero estás comparando manzanas con naranjas con respecto a lo que
wc
está haciendo frente a lo quemd5sum
está haciendo.tarea de md5sum
Cuando
md5sum
procesa un archivo, simplemente abre el archivo como una secuencia y luego comienza a ejecutar la secuencia a través de la función de suma de comprobación MD5 que necesita muy poca memoria. Esencialmente CPU y disco de E / S vinculadas.tarea de wc
Cuando se
wc
ejecuta, está haciendo mucho más que simplemente analizar el archivo de un carácter a la vez. Realmente tiene que analizar la estructura del archivo, líneas a la vez haciendo determinaciones sobre dónde están los límites entre los caracteres y si es un límite de palabra o no.Ejemplo
Piense en las siguientes cadenas y en cómo cada uno de los algoritmos tendría que moverse a través de ellas a medida que las analizan:
Para MD5, trivialmente se mueve a través de estas cadenas de un carácter a la vez. por
wc
ello tiene que decidir qué es un límite de palabra y línea y realizar un seguimiento de la cantidad de ocurrencias que ve.Discusiones adicionales de wc
Encontré este desafío de codificación de 2006 que analiza la implementación
wc
en .NET. Las dificultades son bastante obvias cuando observa algunos de los pseudocódigos, por lo que esto podría ayudar a comenzar a arrojar luz sobre por quéwc
parece ser mucho más lento que otras operaciones.fuente
wc
cuenta varias cosas a medida que analiza el archivo. Cuenta la cantidad de palabras, líneas y bytes a medida que analiza el archivo. ¡Lea la página del manual!wc
que solo contar líneas limita el análisis interno para que solo cuente estas cosas o solo informe los resultados de las líneas, a pesar de que todavía cuenta todo.