Faux pas: La méthode "rapide" que je mentionne ci-dessous n'est pas 60 fois plus rapide que la lente. C'est 30 fois plus rapide. Je vais blâmer l'erreur sur l'heure (3 heures du matin n'est pas mon meilleur moment de la journée pour une réflexion claire :) ..
Mise à jour: j'ai ajouté un résumé des temps de test (ci-dessous).
Il semble y avoir deux problèmes liés au facteur vitesse:
- Le choix de la commande utilisée (comparaisons temporelles indiquées ci-dessous)
- La nature d'un grand nombre de fichiers dans un répertoire ... Il semble que "gros c'est mauvais". Les choses ralentissent de manière disproportionnée à mesure que les chiffres augmentent.
Tous les tests ont été effectués avec 1 million de fichiers.
(les temps réel, utilisateur et sys sont dans les scripts de test)
Les scripts de test peuvent être trouvés sur 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
#
J'ai récemment créé et supprimé 10 millions de fichiers de test vides. Supprimer des fichiers nom par nom (c'est-à-dire rm filename
), j'ai découvert à la dure qu'il y a une énorme différence de temps entre 2 méthodes différentes ...
Les deux méthodes utilisent exactement la même rm filename
commande.
Mise à jour: il s'avère que les commandes n'étaient pas exactement les mêmes ... L'un d'eux envoyait 1000 noms de fichiers à la fois à 'rm' ... C'était un problème d'extension d'accolade du shell où je pensais que chaque nom de fichier était écrit au fichier d'alimentation sur une ligne à part, mais en réalité, il était de 1000 par ligne
Les noms de fichiers sont fournis via un «fichier d'alimentation» dans une while read
boucle.
Le fichier d'alimentation est la sortie de ls -1 -f
Les méthodes sont identiques à tous égards, sauf pour une chose:
- la méthode lente utilise le fichier d'alimentation non trié directement depuis
ls -1 -f
- la méthode rapide utilise une version triée de ce même fichier non trié
Je ne sais pas si le tri est le problème ici, ou est-ce peut-être que le fichier d'alimentation trié correspond simplement à la séquence dans laquelle les fichiers ont été créés (j'ai utilisé un algorithme simple croissant)
Pour 1 million de fichiers, la méthode rapide rm filename
est 60 fois plus rapide que la méthode lente ... encore une fois, je ne sais pas s'il s'agit d'un problème de "tri" ou d'un problème de table de hachage en arrière-plan ... Je soupçonne ce n'est pas un simple problème de tri, car pourquoi me ls -1 -f
donnerait-il intentionnellement une liste non triée d'une séquence de noms de fichiers "triée" fraîchement ajoutée ...
Je me demande simplement ce qui se passe ici, donc il ne me faut pas des jours (oui des jours) pour supprimer les 10 millions de fichiers suivants :) .... Je dis "jours" parce que j'ai essayé tant d'alternatives, et le les temps impliqués augmentent de manière disproportionnée par rapport au nombre de fichiers impliqués .. donc je n'ai testé que 1 million en détail
BTW: La suppression des fichiers via la "liste triée" des noms est en fait plus rapide que rm -rf
d'un facteur 2.
et: rm -r
était 30 fois plus lente que la méthode "liste triée"
... mais est "trié" le problème ici? ou est-il plus lié à une méthode de stockage de hachage (ou autre) utilisée par ext4?
La chose qui me laisse perplexe, c'est que chaque appel à rm filename
est sans rapport avec le précédent .. (enfin, au moins c'est de cette façon du point de vue 'bash')
J'utilise le lecteur Ubuntu / bash / 'ext4' / SATA II.
la source
find -delete
?cat
à un nouveau fichier avant le 1er test - à la placesort
avant le 2e test.Réponses:
rm -r devrait être lent car récursif. Une première traversée en profondeur doit être effectuée sur la structure du répertoire.
Maintenant, comment avez-vous créé 10 millions de fichiers? avez-vous utilisé un script qui boucle dans un certain ordre? 1.txt, 2.txt, 3.txt ... si oui, ces fichiers peuvent également être alloués dans le même ordre dans des blocs contigus dans hdd.so, la suppression dans le même ordre sera plus rapide.
"ls -f" activera -aU qui liste dans l'ordre du répertoire qui est à nouveau récursif.
la source
Vous devez optimiser la structure du fichier. Donc au lieu de
faire quelque chose de plus intelligent comme (supposé bash):
Maintenant, cet exemple est plutôt lent en raison de l'utilisation de md5sum [1], utilisez quelque chose comme le suivant pour une réponse beaucoup plus rapide, tant que vous n'avez pas besoin de noms de fichiers particuliers, les doublons ne sont pas un problème et il n'y a pas besoin d'un hachage répétable d'un certain nom :)
Bien sûr, ce sont tous des concepts empruntés à des tables de hachage
la source