Forum Astuces.divers [Terminal] faire du grep plus rapidement!

Posté par  .
Étiquettes : aucune
0
21
mar.
2004
Comment faire pour que grep aille plus vite?
Utilisez l'option --mmap !

Exemple:
comparez sur plusieurs itérations la sortie de

"time grep --mmap chaine gros_fichier_texte"

et

"time grep chaine gros_fichier_texte"

/!\ Attention /!\ cependant:
la page de man parle de possibles core dumps si
gros_fichier_texte grossit ou si il y a des erreurs
d'E/S (comparez les valeurs sys de la sortie de time).
  • # Re: faire du grep plus rapidement!

    Posté par  . Évalué à 1.

    pour un peu que tu veuilles te faire chier, l'idée est pas forcément mauvaise. Mais le temps de taper --mmap, tu l'as compté celui-là ?


    :)
    -->[]
  • # Re: faire du grep plus rapidement!

    Posté par  (site web personnel) . Évalué à 2.

    " In some situations, --mmap yields better performance. "

    Je n'ai pas regardé en détail la différence de traitement, mais est ce que ça veut dire que l'on peut perdre en performances ?

    " However, --mmap can cause undefined behavior "

    Dans ce cas, on gagne peut etre en performance mais si le resultat n'est pas le "bon" je crains que l'utilisation soit particulièrement risquée.

    Il faudrait plutot savoir le fonctionne exacte de l'option --mmap afin de déterminer quels sont les cas qui peuvent créer des erreurs.

    <a voir>
    • [^] # Re: faire du grep plus rapidement!

      Posté par  (site web personnel) . Évalué à 1.

      Voir mmap(2).

      Je l'ai jamais utilisé mais apparement le principe c'est de faire en sorte que le fichier soit accessible directement en mémoire sans passer par fopen(3) et compagnie et c'est donc à l'OS de gérer les I/O, grep(1) ne fait plus lui même les fread(3)/read(2) et c'est donc censé être plus rapide. Evidemment si le fichier change après l'appel de mmap(2) il risque d'y avoir des problèmes.

      Donc pour répondre à la question "peut-on y perdre en performance ?", je pense que si mmap(2) n'est pas implémenté, oui puisqu'il y aura un appel à mmap(2) qui va échouer puis seulement aura lieu l'ouverture normale du fichier mais la perte de temps doit être marginale. Le principal problème c'est si le fichier est modifié après l'appel à mmap(2), soit
      1/ le fichier garde la même taille
      1.a/ la partie modifiée se situe après la partie qui est en train d'être traitée et donc tout va bien
      1.b/ la partie modifiée se situe avant la partie qui est en train d'être traitée et le résultat ne sera pas forcément correct (change pas du cas où on utilise pas --mmap)
      2/ le fichier change de taille
      2.a/ le fichier grossi et on a pas accès à la partie qui a été ajoutée donc résultat incorrect
      2.b/ le fichier rétreci et on a un problème (probablement un segfault) quand on essai d'accéder à la partie qui se trouve après la fin du fichier actuel
      3/ ya un problème à un certains moment pendant la lecture du fichier et donc segfault quand grep essai d'accéder à la partie concernée

      Pour plus de détails je suppose qu'aller voir les sources de grep(1) est le plus approprié.

      pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.

    • [^] # Re: faire du grep plus rapidement!

      Posté par  . Évalué à 1.

      Je pense que chaque fois que l'on traite un fichier en read-only, on devrait utiliser mmap. Cela laisse carte blanche à l'OS quant à la manière dont il va gérer le chargement. Le mappage d'un fichier en mémoire s'appuie sur la gestion de la mémoire virtuelle, à ceci près que les données sont directement lues ou écrites dans le fichier concerné plutôt que dans un fichier ou une partition de swap.

      C'est vraiment ce qu'il y a de plus rapide et de plus simple à la fois.

      En revanche, pour utiliser mmap, il faut forcément que:
      • Le fichier soit un fichier régulier et de taille définie (on ne s'imaginerait pas mapper en mémoire un truc comme /dev/zero par exemple);
      • Dé préférence, avoir le fichier sur un filesystem local, sinon tout le gain en performance est grêvé par les accès réseau, dont on ne peut d'ailleurs plus prévoir quand ils auront lieu. Et même sans cela, en local, le système peut faire des optimisations et aller lire directement les secteurs du disque. Sur d'autres filesystem, la fonction doit quand même passer par des appels fichiers standard.


      Ceci dit, ces deux conditions sont remplies 90% du temps. De plus, quand on travaille sur des fichiers de plusieurs Gigas, cela permet au système de savoir exactement ce que tu comptes faire et de s'organiser en conséquence. Si tu travailles sur une machine multi-utilisateurs, tes collègues t'en seront reconnaissants.
  • # logs

    Posté par  . Évalué à 1.

    Cela peut se révéler très intéressant pour traiter des fichiers de logs, surtout si ils sont nombreux.

    En effet, ceux-ci ont beau changer, on ne veux en général pas traiter les parties les plus récentes (ou alors on fait un tail), et si ils changent c'est par ajout à la fin du fichier, ce qui ne risque pas de faire dumper son core à grep.

    Je m'en sers pour parcourir des logs web à la recherche de certains types de requêtes par exemple : sur des sites très fréquentés où les logs font plusieurs centaines de Mo malgré la rotation, c'est appréciable. De plus, on charge moins la machine, en production ça présente un intérêt certain.

    Merci pour cette astuce :)
    • [^] # Re: logs

      Posté par  . Évalué à 1.

      j'oubliais : je n'ai jamais réussi à faire planter grep avec des logs, au cas où vous en douteriez, mais il va de soi que pour un script ou quoi que ce soit de récurrent qui a besoin d'être fiable à 100%, il vaut mieux ne pas utiliser cette option, quitte à charger un peu plus la machine. Un bon vieux nice est plus indiqué pour ne pas pénaliser les autres services dans ces cas là.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.