Logo Zéphyrnet

Votre modèle mental des pipelines Bash est-il erroné ?

Date :

[Michael Lynch] a rencontré une situation étrange. Pourquoi compiler puis exécuter son programme près de 10x plus rapide que de simplement exécuter le programme tout seul ? [Michael] a rencontré ce problème lors de l'analyse comparative d'un projet de programmation, l'a réduit à l'essentiel pour la répétabilité et l'analyse, et a découvert qu'il mettait en évidence un modèle mental incorrect du fonctionnement des pipelines bash.

Voici la situation. La première chose que fait le programme épuré de [Michael] est de démarrer un minuteur. Ensuite, il lit et compte simplement quelques octets de stdin, puis imprime combien de temps il a fallu pour que cela se produise. Lors de l'exécution du programme de test de la manière suivante, cela prend environ 13 microsecondes.

$ echo '00010203040506070809' | xxd -r -p | zig build run -Doptimize=ReleaseFast
bytes: 10
execution time: 13.549µs

Lors de l'exécution directe du programme (déjà compilé), le temps d'exécution passe à 162 microsecondes.

$ echo '00010203040506070809' | xxd -r -p | ./zig-out/bin/count-bytes
bytes: 10
execution time: 162.195µs

Encore une fois, la seule différence entre zig build run ainsi que ./zig-out/bin/count-bytes c'est que le premier compile le code, puis l'exécute immédiatement. Le second exécute simplement le programme compilé.

Comment ajouter une étape de compilation supplémentaire diminuer le temps d'exécution ? Il s'avère que le modèle mental de [Michael] sur le fonctionnement des pipelines bash était incorrect, et il fait un excellent travail de expliquant comment ils fonctionnent réellement et pourquoi cela a provoqué ce comportement étrange il voyait.

En bref, les commandes d'un pipeline bash ne sont pas lancées de manière séquentielle. Ils sont tous lancés en même temps et s'exécutent en parallèle. Cela signifiait que lorsqu'il était exécuté directement, le programme de compteur d'octets de [Michael] se lançait immédiatement. Ensuite, il a attendu sans rien faire pendant environ 150 microsecondes pendant que le echo '00010203040506070809' | xxd -r -p une partie du pipeline s'est mise à fournir ses données pour que le programme puisse les lire. C'est de là que vient le temps d'exécution supplémentaire lors de l'exécution de la version déjà compilée.

Alors pourquoi la compilation s'exécute-t-elle d'abord plus rapidement ? Même raison fondamentale : lorsque le zig build run La commande démarre, elle passe d'abord un peu de temps à compiler le programme. Ensuite, lorsque le programme compilé est réellement lancé (et commence son chronomètre d'exécution), les données d'entrée du pipeline bash sont déjà prêtes. Ainsi, le programme fraîchement compilé s'exécute en moins de temps car il n'attend pas que les données antérieures dans le pipeline soient disponibles.

C'est un aperçu intéressant de la façon dont les pipelines bash fonctionnent réellement sous le capot, et nous sommes ravis des détails que [Micheal] met dans l'ensemble du voyage et de l'explication. Tôt ou tard, des détails comme celui-ci apparaissent et font sourciller certains, comme l'utilisateur qui a découvert cas extrêmes gênants concernant les espaces dans les commandes ssh.

spot_img

Dernières informations

spot_img