Laissez-moi vous donner un exemple:
$ 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
Ici vous pouvez voir que la commande yes
écrit des 11504640
lignes en une seconde alors que je ne peux écrire que des 1953
lignes en 5 secondes en utilisant bash for
et echo
.
Comme suggéré dans les commentaires, il existe différentes astuces pour le rendre plus efficace, mais aucune ne correspond à la vitesse 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
Ceux-ci peuvent écrire jusqu'à 20 000 lignes en une seconde. Et ils peuvent être encore améliorés pour:
$ 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
Cela nous amène à 40 000 lignes en une seconde. Mieux, mais loin de là, yes
on peut écrire environ 11 millions de lignes en une seconde!
Alors, comment yes
écrire dans un fichier si rapidement?
date
poids est assez lourd. En outre, le shell doit rouvrir le flux de sortie echo
pour chaque itération de la boucle. Dans le premier exemple, il n'y a qu'une seule invocation de commande avec une seule redirection de sortie, et la commande est extrêmement légère. Les deux ne sont nullement comparables.
date
peut être lourd, voir modifier à ma question.
timeout 1 $(while true; do echo "GNU">>file2; done;)
est la mauvaise façon d'utiliser timeout
car la timeout
commande ne démarrera qu'une fois la substitution de commande terminée. Utilisez timeout 1 sh -c 'while true; do echo "GNU">>file2; done'
.
write(2)
appels système, et non aux charges de bateaux d'autres appels système, à la surcharge du shell ou même à la création de processus dans votre tout premier exemple (qui s'exécute et attend date
pour chaque ligne imprimée dans le fichier). Une seconde d’écriture suffit à peine à goulot d’étranglement sur les E / S du disque (plutôt que sur le processeur / la mémoire), sur un système moderne disposant de beaucoup de RAM. Si on laisse courir plus longtemps, la différence serait moins grande. (En fonction de la qualité de votre implémentation bash et de la vitesse relative du processeur et du disque, il est possible que vous ne saturiez même pas les E / S du disque avec bash).