[Michael Lynch] napotkał dziwną sytuację. Dlaczego kompilował, a następnie uruchamiał swój program prawie 10 razy szybciej niż samo uruchomienie programu? [Michael] natknął się na ten problem podczas porównywania projektu programistycznego, ograniczył go do najważniejszych elementów związanych z powtarzalnością i analizą i odkrył, że uwypuklił on nieprawidłowy mentalny model działania potoków bash.
Oto sytuacja. Pierwszą rzeczą, jaką robi uproszczony program [Michaela], jest uruchomienie timera. Następnie po prostu czyta i zlicza niektóre bajty stdin
, a następnie wypisuje, ile czasu minęło, zanim to nastąpiło. Uruchamianie programu testowego w następujący sposób zajmuje około 13 mikrosekund.
$ echo '00010203040506070809' | xxd -r -p | zig build run -Doptimize=ReleaseFast bytes: 10 execution time: 13.549µs
Przy bezpośrednim uruchomieniu (już skompilowanego) programu czas wykonania wzrasta do 162 mikrosekund.
$ echo '00010203040506070809' | xxd -r -p | ./zig-out/bin/count-bytes bytes: 10 execution time: 162.195µs
Ponownie, jedyna różnica pomiędzy zig build run
i ./zig-out/bin/count-bytes
polega na tym, że najpierw kompiluje kod, a następnie natychmiast go uruchamia. Drugi po prostu uruchamia skompilowany program.
Jak dodać dodatkowy krok kompilacji spadek czas realizacji? Okazuje się, że mentalny model działania potoków bashowych [Michaela] był nieprawidłowy i radzi sobie świetnie wyjaśniając, jak faktycznie działają i dlaczego spowodowało to dziwne zachowanie widział.
Krótko mówiąc, polecenia w potoku bash nie są uruchamiane sekwencyjnie. Wszystkie są uruchamiane w tym samym czasie i wykonywane równolegle. Oznaczało to, że po bezpośrednim uruchomieniu program [Michaela] liczący bajty uruchamiał się natychmiast. Następnie czekał, nic nie robiąc, przez około 150 mikrosekund, podczas gdy echo '00010203040506070809' | xxd -r -p
część potoku zabrała się za dostarczanie danych do programu do odczytania. Stąd bierze się dodatkowy czas wykonania podczas uruchamiania już skompilowanej wersji.
Dlaczego więc kompilacja przebiega szybciej? Z tego samego podstawowego powodu: kiedy zig build run
polecenie się uruchamia, najpierw zajmuje trochę czasu na kompilację programu. Następnie, kiedy skompilowany program zostanie faktycznie uruchomiony (i rozpocznie się jego licznik czasu wykonania), dane wejściowe z potoku bash będą już gotowe. Zatem świeżo skompilowany program wykonuje się w krótszym czasie, ponieważ nie czeka, aż staną się dostępne dane z wcześniejszej fazy potoku.
To interesujące spojrzenie na to, jak faktycznie działają potoki bashowe pod maską i jesteśmy zachwyceni szczegółami, jakie [Micheal] wkłada w całą podróż i wyjaśnienia. Wcześniej czy później takie szczegóły pojawiają się i powodują uniesienie brwi, podobnie jak użytkownik, który odkrył kłopotliwe przypadki Edge dotyczące spacji w poleceniach ssh.
- Dystrybucja treści i PR oparta na SEO. Uzyskaj wzmocnienie już dziś.
- PlatoData.Network Pionowe generatywne AI. Wzmocnij się. Dostęp tutaj.
- PlatoAiStream. Inteligencja Web3. Wiedza wzmocniona. Dostęp tutaj.
- PlatonESG. Węgiel Czysta technologia, Energia, Środowisko, Słoneczny, Gospodarowanie odpadami. Dostęp tutaj.
- Platon Zdrowie. Inteligencja w zakresie biotechnologii i badań klinicznych. Dostęp tutaj.
- Źródło: https://hackaday.com/2024/03/28/is-your-mental-model-of-bash-pipelines-wrong/