Je l'ai découvert:
La raison en est que gzip
(en termes de vitesse du processeur vs vitesse de recherche HD de nos jours) fonctionne des tailles de tampon extrêmement faibles .
Il lit quelques Ko du fichier d'entrée, le compresse et le vide dans le fichier de sortie. Étant donné que cela nécessite une recherche de disque dur, seules quelques opérations peuvent être effectuées par seconde.
La raison pour laquelle ma performance n'a pas évolué, c'est que déjà on gzip
cherchait comme un fou.
J'ai travaillé autour de cela en utilisant l' buffer
utilitaire unix :
buffer -s 100000 -m 10000000 -p 100 < file1.json | gzip > file1.json.gz
En mettant en mémoire tampon beaucoup d'entrées avant de les envoyer à gzip, le nombre de petites recherches peut être considérablement réduit. Les options:
-s
et -m
doivent spécifier la taille du tampon (je pense que c'est en Ko, mais je ne suis pas sûr)
-p 100
s'assure que les données ne sont transmises à gzip qu'une fois le tampon rempli à 100%
En exécutant quatre d'entre eux en parallèle, je pouvais obtenir un débit de 4 * 25 Mo / s, comme prévu.
Je me demande toujours pourquoi gzip ne permet pas d'augmenter la taille du tampon - de cette façon, il est assez inutile s'il est exécuté sur un disque en rotation.
EDIT : J'ai essayé quelques comportements de programmes de compression supplémentaires:
bzip2
ne traite que 2 Mo / s en raison de sa compression plus forte / plus intensive en CPU
lzop
semble autoriser des tampons plus importants: 70 Mo / s par cœur et 2 cœurs peuvent maximiser ma HD sans sur-rechercher
dd
faire la même chose?dd
peut faire la même chose avec sonbs=
option, oui.Après avoir regardé les cinq premières conférences du MIT OpenCourseware pour 6.172: "Performance Engineering of Software Systems", j'ai exécuté l'analyseur de performances Linux "perf" sur un fichier de test modérément volumineux. Le résultat semble montrer les arrêts de pipeline où une instruction doit attendre le résultat d'une précédente.
L'avant-dernière instruction est en cours de copie
%ecx
et la dernière doit attendre (blocage du pipeline) jusqu'à ce que le%cx
registre ait des données prêtes à être utilisées. Ce blocage de pipeline retient la boucle conteneur.Ceci est le résultat d'un style de programmation C «old-school» vraiment obscur.
la source
Une astuce qui pourrait l'amener à un autre niveau de vitesse sur un processeur multicœur / hyperthreading:
(en supposant Ubuntu)
moreutils contient entre autres "gnu parallel" - qui a beaucoup d'options pour vous aider à utiliser plus de votre CPU.
la source