Lassen Sie mich ein Beispiel geben:
$ 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
Hier können Sie sehen, dass der Befehl Zeilen in einer Sekunde yes
schreibt 11504640
, während ich 1953
mit bashs for
und nur Zeilen in 5 Sekunden schreiben kann echo
.
Wie in den Kommentaren vorgeschlagen, gibt es verschiedene Tricks, um die Effizienz zu steigern, aber keine entspricht in etwa der Geschwindigkeit von 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
Diese können bis zu 20.000 Zeilen pro Sekunde schreiben. Und sie können weiter verbessert werden, um:
$ 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
Diese bringen uns in einer Sekunde bis zu 40.000 Zeilen. Besser, aber noch weit entfernt, mit yes
dem man in einer Sekunde ungefähr 11 Millionen Zeilen schreiben kann!
Also, wie yes
schreibt man so schnell in eine Datei?
date
sind etwas schwergewichtig. Außerdem muss die Shell den Ausgabestream echo
für jede Schleifeniteration erneut öffnen . Im ersten Beispiel gibt es nur einen einzigen Befehlsaufruf mit einer einzigen Ausgabeumleitung, und der Befehl ist äußerst kompakt. Die beiden sind in keiner Weise vergleichbar.
date
kann schwergewichtig sein, siehe meine frage bearbeiten.
timeout 1 $(while true; do echo "GNU">>file2; done;)
ist die falsche Methode, timeout
da der timeout
Befehl erst gestartet wird, wenn die Befehlsersetzung abgeschlossen ist. Verwenden Sie timeout 1 sh -c 'while true; do echo "GNU">>file2; done'
.
write(2)
Indem Sie in Ihrem ersten Beispiel nur CPU-Zeit für Systemaufrufe verwenden, nicht für Bootloads anderer Systemaufrufe, Shell-Overhead oder sogar für die Erstellung von Prozessen (die ausgeführt werden und auf date
jede Zeile warten, die in der Datei gedruckt wird). Eine Sekunde des Schreibens reicht kaum aus, um auf einem modernen System mit viel RAM einen Engpass bei der Datenträger-E / A (anstelle von CPU / Speicher) zu verursachen. Wenn länger laufen darf, wäre der Unterschied geringer. (Abhängig davon, wie schlecht eine Bash-Implementierung ist und wie schnell die CPU und der Datenträger sind, können Sie die Datenträger-E / A mit Bash möglicherweise nicht einmal auslasten.)