[Michael Lynch] møtte en merkelig situasjon. Hvorfor kjørte kompilering programmet hans nesten 10 ganger raskere enn bare å kjøre programmet alene? [Michael] møtte dette problemet under benchmarking av et programmeringsprosjekt, reduserte det til dets grunnleggende for repeterbarhet og analyse, og oppdaget at det fremhevet en feil mental modell for hvordan bash-rørledninger fungerte.
Her er situasjonen. Det første [Michael] sitt reduserte program gjør er å starte en timer. Så leser den og teller noen byte fra stdin
, og skriver deretter ut hvor lang tid det tok før det skjedde. Når du kjører testprogrammet på følgende måte, tar det ca. 13 mikrosekunder.
$ echo '00010203040506070809' | xxd -r -p | zig build run -Doptimize=ReleaseFast bytes: 10 execution time: 13.549µs
Når du kjører det (allerede kompilerte) programmet direkte, sveller utførelsestiden til 162 mikrosekunder.
$ echo '00010203040506070809' | xxd -r -p | ./zig-out/bin/count-bytes bytes: 10 execution time: 162.195µs
Igjen, den eneste forskjellen mellom zig build run
og ./zig-out/bin/count-bytes
er at den første kompilerer koden, og deretter kjører den umiddelbart. Den andre kjører ganske enkelt det kompilerte programmet.
Hvordan kan legge til et ekstra kompileringstrinn redusere utførelsestiden? Det viser seg at [Michael]s mentale modell for hvordan bash-rørledninger fungerer var feil, og han gjør en god jobb med forklarer hvordan de faktisk fungerer, og hvorfor det forårsaket den merkelige oppførselen han så.
Kort sagt, kommandoer i en bash-pipeline blir ikke lansert sekvensielt. De lanseres alle samtidig og utføres parallelt. Det betydde at når det ble kjørt direkte, startet [Michael] sitt byte-tellerprogram umiddelbart. Så ventet den rundt og gjorde ingenting i omtrent 150 mikrosekunder mens den echo '00010203040506070809' | xxd -r -p
en del av rørledningen begynte å levere dataene sine for programmet å lese. Det er her den ekstra utførelsestiden kommer fra når du kjører den allerede kompilerte versjonen.
Så hvorfor går det raskere å kompilere det først? Samme grunnleggende årsak: når zig build run
kommandoen starter, bruker den litt tid på å kompilere programmet først. Så når det kompilerte programmet faktisk startes (og starter utførelsestidtakeren), er inndataene fra bash-rørledningen allerede klare. Så det nylig kompilerte programmet kjøres på kortere tid fordi det ikke sitter og venter på at data fra tidligere i pipelinen skal bli tilgjengelig.
Det er et interessant blikk på hvordan bash-rørledninger faktisk fungerer under panseret, og vi er glade for detaljene [Micheal] legger inn i hele reisen og forklaringen. Før eller siden dukker detaljer som dette opp og får noen øyenbryn til å heve seg, som brukeren som oppdaget plagsomme kantsaker angående mellomrom i ssh-kommandoer.
- SEO-drevet innhold og PR-distribusjon. Bli forsterket i dag.
- PlatoData.Network Vertical Generative Ai. Styrk deg selv. Tilgang her.
- PlatoAiStream. Web3 Intelligence. Kunnskap forsterket. Tilgang her.
- PlatoESG. Karbon, CleanTech, Energi, Miljø, Solenergi, Avfallshåndtering. Tilgang her.
- PlatoHelse. Bioteknologisk og klinisk etterretning. Tilgang her.
- kilde: https://hackaday.com/2024/03/28/is-your-mental-model-of-bash-pipelines-wrong/