[Майкл Лінч] зіткнувся з дивною ситуацією. Чому компіляція тоді запускала його програму майже в 10 разів швидше ніж просто запустити програму самостійно? [Майкл] зіткнувся з цією проблемою під час порівняльного аналізу проекту програмування, скоротив його до основних параметрів для повторюваності та аналізу та виявив, що він висвітлює неправильну розумову модель роботи конвеєрів bash.
Ось така ситуація. Перше, що робить скорочена програма [Майкла], це запускає таймер. Потім він просто читає та відраховує кілька байтів stdin
, а потім друкує, скільки часу знадобилося для цього. При виконанні тестової програми таким чином це займає близько 13 мікросекунд.
$ echo '00010203040506070809' | xxd -r -p | zig build run -Doptimize=ReleaseFast bytes: 10 execution time: 13.549µs
При безпосередньому запуску (вже скомпільованої) програми час виконання збільшується до 162 мікросекунд.
$ echo '00010203040506070809' | xxd -r -p | ./zig-out/bin/count-bytes bytes: 10 execution time: 162.195µs
Знову ж таки, єдина різниця між zig build run
та ./zig-out/bin/count-bytes
полягає в тому, що спочатку компілюється код, а потім негайно виконується. Другий просто запускає скомпільовану програму.
Як можна додати додатковий крок компіляції зменшити час виконання? Виявилося, що ментальна модель [Майкла] того, як працюють конвеєри bash, була неправильною, і він чудово справляється з пояснюючи, як вони насправді працюють і чому це спричинило дивну поведінку він бачив.
Коротше кажучи, команди в конвеєрі bash не запускаються послідовно. Усі вони запускаються одночасно й виконуються паралельно. Це означало, що при безпосередньому запуску програма лічильника байтів [Майкла] запускалася негайно. Потім він чекав, нічого не роблячи, близько 150 мікросекунд echo '00010203040506070809' | xxd -r -p
частина конвеєра надала свої дані програмі для читання. Саме звідси виникає додатковий час виконання під час запуску вже скомпільованої версії.
То чому компіляція виконується швидше? Та сама основна причина: коли zig build run
команда запускається, спочатку вона витрачає трохи часу на компіляцію програми. Потім, коли скомпільована програма фактично запускається (і починає свій таймер виконання), вхідні дані з конвеєра bash вже готові. Отже, щойно скомпільована програма виконується за менший час, оскільки вона не чекає, поки стануть доступними дані, отримані раніше в конвеєрі.
Це цікавий погляд на те, як насправді функціонують конвеєри bash під капотом, і ми в захваті від деталей, які [Майкл] вкладає у всю подорож і пояснення. Рано чи пізно такі деталі спливають і викликають підняття брів, як у користувача, який відкрив проблемні крайні випадки щодо пробілів у командах ssh.
- Розповсюдження контенту та PR на основі SEO. Отримайте посилення сьогодні.
- PlatoData.Network Vertical Generative Ai. Додайте собі сили. Доступ тут.
- PlatoAiStream. Web3 Intelligence. Розширення знань. Доступ тут.
- ПлатонЕСГ. вуглець, CleanTech, Енергія, Навколишнє середовище, Сонячна, Поводження з відходами. Доступ тут.
- PlatoHealth. Розвідка про біотехнології та клінічні випробування. Доступ тут.
- джерело: https://hackaday.com/2024/03/28/is-your-mental-model-of-bash-pipelines-wrong/