Zephyrnet-logo

Er din mentale modell av Bash Pipelines feil?

Dato:

[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.

spot_img

Siste etterretning

spot_img