Paso en falso: el método "rápido" que menciono a continuación, no es 60 veces más rápido que el lento. Es 30 veces más rápido. Culparé del error a la hora (3AM no es mi mejor momento del día para pensar claramente :) ..
Actualización: he agregado un resumen de los tiempos de prueba (a continuación).
Parece que hay dos problemas relacionados con el factor de velocidad:
- La elección del comando utilizado (las comparaciones de tiempo se muestran a continuación)
- La naturaleza de un gran número de archivos en un directorio ... Parece que "grande es malo". Las cosas se vuelven desproporcionadamente más lentas a medida que aumentan los números.
Todas las pruebas se han realizado con 1 millón de archivos.
(los tiempos reales, de usuario y sys están en los scripts de prueba)
Los scripts de prueba se pueden encontrar en paste.ubuntu.com
#
# 1 million files
# ===============
#
# |time |new dir |Files added in ASCENDING order
# +---- +------- +-------------------------------------------------
# real 01m 33s Add files only (ASCENDING order) ...just for ref.
# real 02m 04s Add files, and make 'rm' source (ASCENDING order)
# Add files, and make 'rm' source (DESCENDING order)
# real 00m 01s Count of filenames
# real 00m 01s List of filenames, one per line
# ---- ------- ------
# real 01m 34s 'rm -rf dir'
# real 01m 33s 'rm filename' via rm1000filesPerCall (1000 files per 'rm' call)
# real 01m 40s 'rm filename' via ASCENDING algorithm (1000 files per 'rm' call)
# real 01m 46s 'rm filename' via DESCENDING algorithm (1000 files per 'rm' call)
# real 21m 14s 'rm -r dir'
# real 21m 27s 'find dir -name "hello*" -print0 | xargs -0 -n 1000 rm'
# real 21m 56s 'find dir -name "hello*" -delete'
# real 23m 09s 'find dir -name "hello*" -print0 | xargs -0 -P 0 rm'
# real 39m 44s 'rm filename' (one file per rm call) ASCENDING
# real 47m 26s 'rm filename' (one file per rm call) UNSORTED
#
Recientemente creé y eliminé 10 millones de archivos de prueba vacíos. Eliminando archivos nombre por nombre (es decir rm filename
), descubrí por las malas que hay una gran diferencia horaria entre 2 métodos diferentes ...
Ambos métodos usan exactamente el mismo rm filename
comando.
Actualización: resulta que los comandos no eran exactamente los mismos ... Uno de ellos estaba enviando 1000 nombres de archivo a la vez a 'rm' ... Era un problema de expansión de llaves de concha donde pensé que cada nombre de archivo se estaba escribiendo al archivo del alimentador en una línea propia, pero en realidad era 1000 por línea
Los nombres de archivo se proporcionan a través de un 'archivo de alimentación' en un while read
bucle.
El archivo de alimentación es la salida de ls -1 -f
Los métodos son idénticos en todos los aspectos, excepto por una cosa:
- el método lento usa el archivo del alimentador sin clasificar directamente de
ls -1 -f
- el método rápido usa una versión ordenada del mismo archivo sin clasificar
No estoy seguro de si la clasificación es este problema aquí, o tal vez es que el archivo del alimentador ordenado coincide con la secuencia en la que se crearon los archivos (utilicé un algoritmo entero ascendente simple)
Para 1 millón de archivos, el método rápido rm filename
es 60 veces más rápido que el método lento ... de nuevo, no sé si este es un problema de "clasificación" o un problema de tabla hash detrás de escena ... sospecho no es un simple problema de clasificación, porque ¿por qué ls -1 -f
intencionalmente me daría una lista sin ordenar de una secuencia de nombres de archivos "ordenados" recién agregados ...
Me pregunto qué está pasando aquí, así que no me lleva días (sí días) eliminar los próximos 10 millones de archivos :) .... Digo "días" porque probé muchas alternativas, y el los tiempos involucrados aumentan desproporcionadamente en relación con el número de archivos involucrados ... así que solo he probado 1 millón en detalle
Por cierto: eliminar los archivos a través de la "lista ordenada" de nombres es en realidad más rápido que rm -rf
por un factor de 2.
y: rm -r
fue 30 veces más lento que el método de "lista ordenada"
... pero ¿está "resuelto" el problema aquí? ¿O está más relacionado con un método de almacenamiento hash (o lo que sea) utilizado por ext4?
Lo que me desconcierta bastante es que cada llamada a rm filename
no está relacionada con la anterior ... (bueno, al menos es así desde la perspectiva de 'bash')
Estoy usando Ubuntu / bash / 'ext4' / SATA II drive.
fuente
find -delete
?cat
archivo simple a nuevo antes de la primera prueba, en lugar desort
antes de la segunda prueba.Respuestas:
Se espera que rm -r sea lento ya que es recursivo. Se debe realizar un primer recorrido profundo en la estructura del directorio.
Ahora, ¿cómo creaste 10 millones de archivos? ¿Usaste algún script que repite en algún orden? 1.txt, 2.txt, 3.txt ... en caso afirmativo, entonces esos archivos también pueden asignarse en el mismo orden en bloques contigo en hdd, por lo que la eliminación en el mismo orden será más rápida.
"ls -f" habilitará -aU que enumera en orden de directorio que nuevamente es recursivo.
fuente
Debe optimizar la estructura de archivos. Entonces en lugar de
hacer algo más inteligente (bash asumido):
Ahora, este ejemplo es bastante lento debido al uso de md5sum [1], use algo como lo siguiente para obtener una respuesta mucho más rápida, siempre que no necesite ningún nombre de archivo en particular, los duplicados no son una preocupación y no hay necesidad de un hash repetible de cierto nombre :)
Por supuesto, todo esto es prestar conceptos descuidadamente de tablas hash
fuente