Zephyrnet-logo

Is uw mentale model van Bash-pijplijnen verkeerd?

Datum:

[Michael Lynch] kwam een ​​vreemde situatie tegen. Waarom compileerde en draaide zijn programma bijna 10x sneller dan alleen het programma zelf uitvoeren? [Michael] kwam dit probleem tegen toen hij een programmeerproject aan het benchmarken was, bracht het terug tot de essentie voor herhaalbaarheid en analyse, en ontdekte dat het een onjuist mentaal model benadrukte van hoe bash-pijplijnen werkten.

Hier is de situatie. Het eerste dat het uitgeklede programma van [Michael] doet, is een timer starten. Vervolgens leest en telt het eenvoudigweg enkele bytes stdinen drukt vervolgens af hoe lang het duurde voordat dat gebeurde. Wanneer u het testprogramma op de volgende manier uitvoert, duurt dit ongeveer 13 microseconden.

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

Wanneer het (reeds gecompileerde) programma rechtstreeks wordt uitgevoerd, neemt de uitvoeringstijd toe tot 162 microseconden.

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

Nogmaals, het enige verschil tussen zig build run en ./zig-out/bin/count-bytes is dat de code eerst wordt gecompileerd en vervolgens onmiddellijk wordt uitgevoerd. De tweede voert eenvoudigweg het gecompileerde programma uit.

Hoe kan het toevoegen van een extra compileerstap verlagen de uitvoeringstijd? Blijkt dat [Michael]’s mentale model van hoe bash-pijplijnen werken onjuist was, en hij doet geweldig werk uitleggen hoe ze eigenlijk werken, en waarom dat het vreemde gedrag veroorzaakte hij zag.

Kortom, opdrachten in een bash-pijplijn worden niet opeenvolgend gelanceerd. Ze worden allemaal tegelijkertijd gelanceerd en parallel uitgevoerd. Dat betekende dat wanneer het direct werd uitgevoerd, het bytetellerprogramma van [Michael] onmiddellijk werd gelanceerd. Vervolgens wachtte het ongeveer 150 microseconden terwijl het niets bijzonders deed echo '00010203040506070809' | xxd -r -p een deel van de pijplijn slaagde erin zijn gegevens te leveren zodat het programma deze kon lezen. Dit is waar de extra uitvoeringstijd vandaan komt bij het uitvoeren van de reeds gecompileerde versie.

Dus waarom gaat het eerst compileren sneller? Dezelfde basisreden: wanneer de zig build run commando van start gaat, besteedt het eerst wat tijd aan het compileren van het programma. Wanneer het gecompileerde programma vervolgens daadwerkelijk wordt gestart (en de uitvoeringstimer begint), zijn de invoergegevens van de bash-pijplijn al gereed. Het vers gecompileerde programma wordt dus in minder tijd uitgevoerd omdat het niet hoeft te wachten tot gegevens uit een eerder stadium in de pijplijn beschikbaar komen.

Het is een interessante kijk op hoe bash-pijplijnen feitelijk onder de motorkap functioneren, en we zijn blij met de details die [Micheal] in het hele traject en de uitleg stopt. Vroeg of laat duiken dit soort details op en zorgen ervoor dat sommige wenkbrauwen omhoog gaan, zoals bij de gebruiker die het ontdekte lastige randgevallen met betrekking tot spaties in ssh-opdrachten.

spot_img

Laatste intelligentie

spot_img