Zephyrnet-logotyp

Är din mentala modell av Bash Pipelines fel?

Datum:

[Michael Lynch] råkade ut för en konstig situation. Varför körde kompileringen sitt program nästan 10 gånger snabbare än att bara köra programmet själv? [Michael] stötte på det här problemet när han benchmarkade ett programmeringsprojekt, reducerade det till dess väsentligheter för repeterbarhet och analys, och upptäckte att det lyfte fram en felaktig mental modell av hur bash-pipelines fungerade.

Här är situationen. Det första [Michael]s avskalade program gör är att starta en timer. Sedan läser den helt enkelt och räknar några byte från stdin, skriver sedan ut hur lång tid det tog för det att hända. När man kör testprogrammet på följande sätt tar det cirka 13 mikrosekunder.

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

När du kör det (redan kompilerade) programmet direkt, sväller exekveringstiden till 162 mikrosekunder.

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

Återigen, den enda skillnaden mellan zig build run och ./zig-out/bin/count-bytes är att den första kompilerar koden och sedan omedelbart kör den. Den andra kör helt enkelt det kompilerade programmet.

Hur kan man lägga till ett extra kompileringssteg minskning avrättningstiden? Det visar sig att [Michael]s mentala modell av hur bash-pipelines fungerar var felaktig, och han gör ett bra jobb med förklara hur de faktiskt fungerar, och varför det orsakade det konstiga beteendet han såg.

Kort sagt, kommandon i en bash-pipeline startas inte sekventiellt. De lanseras alla samtidigt och körs parallellt. Det innebar att när det kördes direkt, startade [Michael]s byte-räknare omedelbart. Sedan väntade den och gjorde ingenting i cirka 150 mikrosekunder medan den echo '00010203040506070809' | xxd -r -p en del av pipelinen började leverera sina data för programmet att läsa. Det är här den extra körtiden kommer från när du kör den redan kompilerade versionen.

Så varför går det snabbare att kompilera det först? Samma grundläggande anledning: när zig build run kommandot startar, det ägnar lite tid åt att kompilera programmet först. Sedan när det kompilerade programmet faktiskt startas (och börjar sin exekveringstimer), är indata från bash-pipeline redan klar. Så det nykompilerade programmet körs på kortare tid eftersom det inte sitter och väntar på att data från tidigare i pipelinen ska bli tillgängliga.

Det är en intressant titt på hur bash-pipelines faktiskt fungerar under huven, och vi är nöjda med detaljerna som [Micheal] lägger på hela resan och förklaringen. Förr eller senare dyker sådana här detaljer upp och får några ögonbryn att höjas, som användaren som upptäckte besvärliga kantfall angående mellanslag i ssh-kommandon.

plats_img

Senaste intelligens

plats_img