6

一部の出力を3つの異なる方法でファイルにリダイレクトしていますが、それぞれに明らかに異なる時間がかかります。

$ >/tmp/file ; time for i in {1..1000}; do for j in {1..1000}; do echo $i $j >> /tmp/file; done; done

real    0m33.467s
user    0m21.170s
sys     0m11.919s

$ >/tmp/file ; exec 3>/tmp/file; time for i in {1..1000}; do for j in {1..1000}; do echo $i $j >&3; done; done; exec 3>&-

real    0m24.211s
user    0m17.181s
sys     0m7.002s

$ >/tmp/file ; time for i in {1..1000}; do for j in {1..1000}; do echo $i $j; done; done >> /tmp/file 

real    0m17.038s
user    0m13.072s
sys     0m3.945s

誰かがここで違いを説明できますか?私の現在の理解/疑問は次のとおりです。

  1. 1つ目は、ファイルを複数回開いたり閉じたりするので最も遅くなりますが、他の1つは1回だけ実行します。そうですか?バッファリングについてはどうですか。通常、すべての出力がバッファリングされることを期待します。その場合、それほど大きな時間差はありません。
  2. 3番目に、すべての出力が外側のループの最後にのみ書き込まれる場合、ループの実行中にすべての出力が保存されます。おそらくメモリ内。たくさんのことをエコーし​​て最後に書くだけだと、メモリが不足する可能性があるということですか?
  3. 2番目は1番目または3番目に似ています。なぜそれがどちらともそんなに違うのですか。

PS:上記のコマンドを数回実行しましたが、時間が一貫していることがわかりました。ですから、私が見ている違いは、いくつかの本当の理由によるものであるに違いありません。

4

1 に答える 1

1
  1. 最初のバージョンではecho $i $j >> /tmp/file、ファイルを追加用に開き、書き込み、閉じます。

  2. 百万回echo $i $j >&3実行することは、毎回ファイルを開いたり閉じたりするのではなく、ファイル記述子 #3 に書き込むという点で 1 回とは異なります。はexec 3>/tmp/file書き込み用にファイルを開き、ファイル記述子を #3 として保存します。コマンドの stdout がファイル記述子 #3 にリダイレクトされるようになった場合 (>&3エコー後の の効果)、シェルはコマンドを実行する前にこのリダイレクトをセットアップし、その後、以前の割り当てを stdout に復元する必要があります。

  3. このように完全なループの出力をリダイレクトする>> /tmp/fileことは、シェルにとってはるかに簡単です。追加のファイル記述子を設定することなく、単純に echo コマンドを実行できます。stdout の割り当てを一度だけ変更します。

バッファリングについて: 3 つのケースすべてで、基盤となるファイル システムが物理ファイルへのアクセスをバッファリングするため、そのレベルでの違いはありません。また、ほとんどの Linux には /tmp にマウントされた tmpfs があり、とにかく実行するすべての操作を純粋なメモリ操作にします。したがって、ここではIOパフォーマンスを測定していませんが、シェルコマンドの実行パフォーマンスを測定しています。これは、書き込まれるバイト数を増やすことで証明できます (エコー出力の行に定数値を追加します)。

>/tmp/file ; time for i in {1..1000}; do for j in {1..1000}; do echo "1000000 $i $j" >> /tmp/file; done; done

>/tmp/file ; exec 3>/tmp/file; time for i in {1..1000}; do for j in {1..1000}; do echo "1000000 $i $j" >&3; done; done; exec 3>&-

>/tmp/file ; time for i in {1..1000}; do for j in {1..1000}; do echo "1000000 $i $j"; done; done >> /tmp/file

私の PC では、定数 "1000000 " を使用しない場合と同じ時間がかかりますが、2 倍のバイトがファイルに書き込まれます。

于 2012-12-01T12:32:08.383 に答える