Pourquoi [find] court-il incroyablement vite s'il est exécuté deux fois?

4

Le tableau de bord de mon système Ubuntu / Linux contient deux versions du même programme.

Initial Problem

Pour trouver où le correspondant .desktop les fichiers se trouvent j'ai utilisé

find / -type f -name 'Sublime Text.desktop' 2> /dev/null

Je n'ai eu aucun succès, alors je l'ai fait (avec succès)

find / -type f -name '[s,S]ublime*.desktop' 2> /dev/null

J’ai été étonné, j’ai vu qu’il se terminait au bout de trois secondes environ, le terme de recherche devant être plus important que le premier. Comme ce n’était pas silencieux pour moi, j’ai lancé à nouveau la première commande et, à ma grande surprise, il n’a fallu que trois secondes pour terminer.

Pour vérifier le comportement, j’ai alimenté une deuxième machine Linux et exécuté la première commande à nouveau, time

time find -type f -name 'Sublime Text.desktop' 2> /dev/null 

Proof


find accélère non seulement la recherche du même terme de recherche, mais également de toutes les recherches (dans le même chemin?). Même la recherche d'une chaîne "non répétée" n'est pas ralentie.

time find / -type f -name 'Emilbus Txet.Potksed' 2> /dev/null

Analyse RAM while before and after using find

Que fait-on pour accélérer le processus de recherche de manière aussi insensée?

Senkaku
la source
(d’un point de vue extérieur) peut-être trouver un index des résultats qu’il obtient, afin que les prochaines exécutions soient exécutées plus rapidement.
Doktoro Reichard
Serait-il possible d'indexer tous les fichiers trouvés, même ceux qui ne correspondent pas au terme recherché? Cela ne dépasserait-il pas les capacités de stockage de la RAM? Et si non, pourquoi trouver ne pas tout indexer par défaut? S'il ne fait qu'indexer les correspondances, mon dernier exemple avec le terme de recherche inversé ne devrait pas être aussi rapide.
Senkaku
unix.stackexchange.com/questions/40206/grep-second-time-faster
Ciro Santilli 新疆改造中心 六四事件 法轮功

Réponses:

6

La raison pour laquelle la recherche est plus rapide la deuxième fois est que Linux ne file mise en cache . Chaque fois qu'un fichier est accédé pour la première fois, il conserve le contenu du fichier en mémoire (bien sûr, il le fait uniquement lorsque vous avez de la RAM disponible). Si le fichier est relu ultérieurement, il peut alors simplement extraire le contenu de la mémoire sans avoir à relire le fichier. Étant donné que l'accès à la mémoire est beaucoup plus rapide que l'accès au disque, les performances globales augmentent.

Alors qu'est-ce qui se passe est que le premier find, la plupart des fichiers ne sont pas encore en mémoire, donc Linux doit effectuer de nombreuses opérations sur le disque. C'est lent, donc ça prend du temps.

Quand vous exécutez find encore une fois, la plupart des fichiers et des répertoires sont déjà en mémoire et c'est beaucoup plus rapide


Vous pouvez tester vous-même si vous vider le cache entre les deux trouver des exécutions. Ensuite, la deuxième découverte ne sera pas plus rapide que la première. Voici à quoi cela ressemble sur mon système:

# This clears the cache. Be careful through, you might loose some data (Although this shouldn't happen, it's better to be sure)
$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3

$ time find /usr/lib -name "lib*"
find /usr/lib/ -name "lib*"  0,47s user 1,41s system 8% cpu 21,435 total

# Now the file names are in the cache. The next find is very fast:
$ time find /usr/lib -name "lib*"
find /usr/lib/ -name "lib*"  0,19s user 0,28s system 69% cpu 0,673 total

# If we clear the cache, the time goes back to the starting time again
$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time find /usr/lib -name "lib*"
find /usr/lib/ -name "lib*"  0,39s user 1,45s system 10% cpu 16,866 total
bennofs
la source
Étonnant, trouve-t-il en cache chaque fichier / répertoire / lien dans / usr / lib? Si c'est le cas, find / -name 'foo.bar' mettrait en cache l'ensemble du système de fichiers, non? Comme la mise en cache utilise seulement une petite quantité de RAM, y a-t-il une raison pour laquelle le système d'exploitation ne met pas en cache l'ensemble du système de fichiers par défaut, dès que le disque dur / SSD est inactif? PS: Pourriez-vous ajouter un commentaire à la deuxième ligne de votre script? Je ne comprends pas pourquoi vous écrivez 3 à /proc/sys/vm/drop_caches.
Senkaku
1
@ th3m3s je suppose que find / ... met en cache uniquement les noms de fichier / contenu du répertoire. Je pense que le système de fichiers entier n'est pas mis en cache par défaut, il est nécessaire de le mettre en cache gratuitement pour d'autres tâches, par exemple les fichiers que vous lisez.
bennofs
1
Correct, find n'a pas accès à la Contenu des fichiers, uniquement la structure de répertoire et les noms de fichier, de sorte qu'il ne cache que cette partie. En règle générale, chaque fois qu'un fichier est lu via l'appel du noyau approprié, Linux vérifie d'abord la RAM pour voir s'il est présent, et sinon: le lit réellement sur le disque (et le stocke normalement dans la RAM pour une recherche ultérieure). On peut voir directement que cette recherche supplémentaire doit avoir un impact négatif sur les performances si les fichiers en cache ne sont jamais trouvés, mais le "profit" substantiel lorsque vous avez un cache atteint dépasse de loin cette valeur.
Daniel Andersson
1
Il y a encore plus que ça. Vous pouvez tout mettre en cache, mais il doit quand même être réceptif aux changements pour pouvoir toujours obtenir des résultats précis.
Dustin Oprea