Zephyrnet-Logo

Ist Ihr mentales Modell von Bash-Pipelines falsch?

Datum:

[Michael Lynch] erlebte eine seltsame Situation. Warum wurde sein Programm fast zehnmal kompiliert und dann ausgeführt? beschleunigt als das Programm einfach alleine auszuführen? [Michael] stieß beim Benchmarking eines Programmierprojekts auf dieses Problem, reduzierte es auf das Wesentliche für Wiederholbarkeit und Analyse und stellte fest, dass es ein falsches mentales Modell der Funktionsweise von Bash-Pipelines hervorhob.

Hier ist die Situation. Das erste, was [Michaels] abgespecktes Programm tut, ist, einen Timer zu starten. Dann liest und zählt es einfach einige Bytes von stdinund gibt dann aus, wie lange es gedauert hat, bis das passiert ist. Wenn das Testprogramm wie folgt ausgeführt wird, dauert es etwa 13 Mikrosekunden.

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

Bei direkter Ausführung des (bereits kompilierten) Programms erhöht sich die Ausführungszeit auf 162 Mikrosekunden.

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

Auch hier der einzige Unterschied zwischen zig build run und ./zig-out/bin/count-bytes besteht darin, dass zuerst der Code kompiliert und dann sofort ausgeführt wird. Der zweite führt einfach das kompilierte Programm aus.

Wie kann ein zusätzlicher Kompilierungsschritt hinzugefügt werden? verringern die Ausführungszeit? Es stellte sich heraus, dass [Michaels] mentales Modell der Funktionsweise von Bash-Pipelines falsch war, und er leistet hervorragende Arbeit Erklären Sie, wie sie tatsächlich funktionieren und warum dies das seltsame Verhalten verursacht er sah.

Kurz gesagt, Befehle in einer Bash-Pipeline werden nicht nacheinander gestartet. Sie werden alle gleichzeitig gestartet und parallel ausgeführt. Das bedeutete, dass das Bytezählerprogramm von [Michael] bei direkter Ausführung sofort startete. Dann wartete es etwa 150 Mikrosekunden lang, ohne viel zu tun, während das echo '00010203040506070809' | xxd -r -p Ein Teil der Pipeline hat es geschafft, seine Daten zum Lesen durch das Programm bereitzustellen. Hierher kommt die zusätzliche Ausführungszeit, wenn die bereits kompilierte Version ausgeführt wird.

Warum läuft das Kompilieren dann schneller? Derselbe grundlegende Grund: wenn die zig build run Wenn der Befehl gestartet wird, dauert es zunächst ein wenig, das Programm zu kompilieren. Wenn dann das kompilierte Programm tatsächlich gestartet wird (und sein Ausführungstimer beginnt), sind die Eingabedaten aus der Bash-Pipeline bereits bereit. Das frisch kompilierte Programm wird also in kürzerer Zeit ausgeführt, da es nicht darauf wartet, dass Daten von früher in der Pipeline verfügbar werden.

Es ist ein interessanter Blick darauf, wie Bash-Pipelines tatsächlich unter der Haube funktionieren, und wir sind begeistert von den Details, die [Micheal] in die gesamte Reise und Erklärung einbringt. Früher oder später tauchen Details wie diese auf und sorgen für Stirnrunzeln, wie der Benutzer, der es entdeckt hat problematische Randfälle bezüglich Leerzeichen in SSH-Befehlen.

spot_img

Neueste Intelligenz

spot_img