Zephyrnet Logo

O seu modelo mental de pipelines Bash está errado?

Data:

[Michael Lynch] encontrou uma situação estranha. Por que compilar e executar seu programa quase 10x mais rápido do que apenas executar o programa sozinho? [Michael] se deparou com esse problema ao avaliar um projeto de programação, reduziu-o ao essencial para repetibilidade e análise e descobriu que ele destacava um modelo mental incorreto de como funcionavam os pipelines bash.

Aqui está a situação. A primeira coisa que o programa reduzido de [Michael] faz é iniciar um cronômetro. Então ele simplesmente lê e conta alguns bytes de stdine imprime quanto tempo levou para isso acontecer. Ao executar o programa de teste da seguinte maneira, leva cerca de 13 microssegundos.

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

Ao executar o programa (já compilado) diretamente, o tempo de execução aumenta para 162 microssegundos.

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

Novamente, a única diferença entre zig build run e ./zig-out/bin/count-bytes é que o primeiro compila o código e depois o executa imediatamente. O segundo simplesmente executa o programa compilado.

Como adicionar uma etapa extra de compilação diminuir o tempo de execução? Acontece que o modelo mental de [Michael] de como os pipelines do bash funcionam estava incorreto, e ele faz um ótimo trabalho explicando como eles realmente funcionam e por que isso causou o comportamento estranho ele estava vendo.

Resumindo, os comandos em um pipeline bash não são iniciados sequencialmente. Todos eles são iniciados ao mesmo tempo e executados em paralelo. Isso significava que, quando executado diretamente, o programa contador de bytes de [Michael] era iniciado imediatamente. Então ele esperou sem fazer muita coisa por cerca de 150 microssegundos enquanto o echo '00010203040506070809' | xxd -r -p parte do pipeline entregou seus dados para o programa ler. É daí que vem o tempo extra de execução ao executar a versão já compilada.

Então, por que compilá-lo primeiro é mais rápido? Mesma razão básica: quando o zig build run O comando é iniciado, ele gasta um pouco de tempo compilando o programa primeiro. Então, quando o programa compilado for realmente iniciado (e iniciar seu cronômetro de execução), os dados de entrada do pipeline bash já estarão prontos. Assim, o programa recém-compilado é executado em menos tempo porque não fica parado esperando que os dados anteriores no pipeline fiquem disponíveis.

É uma visão interessante de como os pipelines do bash realmente funcionam nos bastidores, e estamos encantados com os detalhes que [Micheal] coloca em toda a jornada e explicação. Mais cedo ou mais tarde, detalhes como esse surgem e levantam algumas sobrancelhas, como o usuário que descobriu casos extremos problemáticos relacionados a espaços em comandos ssh.

local_img

Inteligência mais recente

local_img