tl; dr - The zig build run
version appeared to run faster because it wasn’t waiting on echo
or xxd
to feed input to stdin.
To close the loop on this, Andrew Ayer explained the phenomenon I was observing.
My mental model was that echo
ran, then piped its results to xxd
, then xxd
finished and piped its results to my Zig program.
But actually in a bash pipeline, all the commands in the pipeline start at the same time.
The reason why I measured slower performance in the ./count-bytes
invocation was that it was actually running faster. The binary started the timer immediately and then had to block on the countBytes
call for input to arrive from xxd
, which hadn’t started producing output yet.
In the zig build run
version, what was probably happening was that calling zig build run
rather than ./count-bytes
meant that count-bytes
timer started later, as the overhead of zig build
probably adds 100+ms. So, instead of count-bytes
starting immediately and then having to wait ~100ms for echo
and xxd
to get input into stdin, by the time the zig build run
version starts the program, echo
and xxd
have finished their work, so count-bytes
doesn’t have to wait to read from stdin.