Deixe-me dar um exemplo:
$ timeout 1 yes "GNU" > file1
$ wc -l file1
11504640 file1
$ for ((sec0=`date +%S`;sec<=$(($sec0+5));sec=`date +%S`)); do echo "GNU" >> file2; done
$ wc -l file2
1953 file2
Aqui você pode ver que o comando yes
escreve 11504640
linhas em um segundo, enquanto eu posso escrever apenas 1953
linhas em 5 segundos usando bash for
e echo
.
Conforme sugerido nos comentários, existem vários truques para torná-lo mais eficiente, mas nenhum chega nem perto de corresponder à velocidade de yes
:
$ ( while :; do echo "GNU" >> file3; done) & pid=$! ; sleep 1 ; kill $pid
[1] 3054
$ wc -l file3
19596 file3
$ timeout 1 bash -c 'while true; do echo "GNU" >> file4; done'
$ wc -l file4
18912 file4
Eles podem escrever até 20 mil linhas em um segundo. E eles podem ser melhorados ainda mais para:
$ timeout 1 bash -c 'while true; do echo "GNU"; done >> file5'
$ wc -l file5
34517 file5
$ ( while :; do echo "GNU"; done >> file6 ) & pid=$! ; sleep 1 ; kill $pid
[1] 5690
$ wc -l file6
40961 file6
Isso nos leva a 40 mil linhas em um segundo. Melhor, mas ainda muito longe do yes
qual pode escrever cerca de 11 milhões de linhas em um segundo!
Então, como yes
gravar no arquivo tão rapidamente?
date
é um pouco pesado, além disso, o shell precisa reabrir o fluxo de saída echo
para cada iteração do loop. No primeiro exemplo, existe apenas uma chamada de comando com um redirecionamento de saída único, e o comando é extremamente leve. Os dois não são de forma alguma comparáveis.
date
pode ser muito pesado, veja editar a minha pergunta.
timeout 1 $(while true; do echo "GNU">>file2; done;)
é a maneira errada de usar, timeout
pois o timeout
comando será iniciado apenas quando a substituição do comando for concluída. Use timeout 1 sh -c 'while true; do echo "GNU">>file2; done'
.
write(2)
chamadas do sistema, não em cargas de barco de outros syscalls, sobrecarga de shell ou até mesmo criação de processo no seu primeiro exemplo (que executa e aguarda date
por cada linha impressa no arquivo). Um segundo de gravação é suficiente para afunilar a E / S do disco (em vez da CPU / memória), em um sistema moderno com muita RAM. Se for permitido executar mais, a diferença seria menor. (Dependendo do grau de implementação ruim do bash e da velocidade relativa da CPU e do disco, você pode nem saturar a E / S do disco com o bash).