>ファイルがechoよりもリアルタイムを使用する理由| sed> file?


28

以下の例は私を驚かせました。それは、直感に反するようです... コンボのためのより多くのユーザー時間があるという事実は別としてecho | sed

単独で実行する場合echo、なぜそんなに多くのsys時間を使用するのでしょうか、または質問sedは「プレイの状態をどのように変更するのですか?」と思われるechoでしょうが、同じ行う必要があるエコー-INGのを両方のケースで...

time echo -n a\ {1..1000000}\ c$'\n' >file

# real    0m9.481s
# user    0m5.304s
# sys     0m4.172s

time echo -n a\ {1..1000000}\ c$'\n' |sed s/^\ // >file

# real    0m5.955s
# user    0m5.488s
# sys     0m1.580s

1
私の腸の反応は、それがバッファリングに関係しているということです。
バハマ

1
@bahamatあなたは正しいと思います。エコーは、引数ごとに個別のwrite()を実行します。sedはそれらをバッファリングします。したがって、最初のバージョンでは、ファイルシステムドライバーを経由してブロックデバイスレイヤーに移動する通常ファイルへの100万回の書き込みがあり、2番目のバージョンでは、パイプに行く100万回の書き込みと、カーネルコードのより高価なレイヤーを通過する書き込みが多少少なくなります。
アランカレー

@bahamat間違いなくバッファリング。time echo ... |cat >fileまたtime echo ... |perl -ne 'print'sedバージョンと同様の時間です。
StarNamer

4
良い説明をしてくれたみんなに感謝します...だから、大きな複数行の書き込み(bashで)の場合、猫は猫の有用な使用法を獲得しました:)
Peter.O

回答:


29

bahamatとAlan Curryが正解です。これは、シェルがの出力をバッファリングする方法によるものですecho。具体的には、シェルはbashであり、write1行に1つのシステムコールを発行します。したがって、最初のスニペットはディスクファイルに1000000回の書き込みを行い、2番目のスニペットはパイプとsed(複数のCPUがある場合はほぼ並行して)に1000000回の書き込みを行い、その出力によりディスクファイルへの書き込み回数を大幅に減らしますバッファリング。

straceを実行すると、何が起こっているかを観察できます。

$ strace -f -e write bash -c 'echo -n a\ {1..2}\ c$'\'\\n\'' >file'
write(1, "a 1 c\n", 6)                  = 6
write(1, " a 2 c\n", 7)                 = 7
$ strace -f -e write bash -c 'echo -n a\ {1..2}\ c$'\'\\n\'' | sed "s/^ //" >file'
Process 28052 attached
Process 28053 attached
Process 28051 suspended
[pid 28052] write(1, "a 1 c\n", 6)      = 6
[pid 28052] write(1, " a 2 c\n", 7)     = 7
Process 28051 resumed
Process 28052 detached
Process 28051 suspended
[pid 28053] write(1, "a 1 c\na 2 c\n", 12) = 12
Process 28051 resumed
Process 28053 detached
--- SIGCHLD (Child exited) @ 0 (0) ---

kshなどの他のシェルはecho、複数行であっても出力をバッファリングするため、大きな違いは見られません。

$ strace -f -e write ksh -c 'echo -n a\ {1..2}\ c$'\'\\n\'' >file'
write(1, "a 1 c\n a 2 c\n", 13)         = 13
$ strace -f -e write ksh -c 'echo -n a\ {1..2}\ c$'\'\\n\'' | sed "s/^ //" >file'
Process 28058 attached
[pid 28058] write(1, "a 1 c\n a 2 c\n", 13) = 13
Process 28058 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
write(1, "a 1 c\na 2 c\n", 12)          = 12

bashでは、同様のタイミング比率が得られます。kshでは、2番目のスニペットの実行速度が遅くなります。

ksh$ time echo -n a\ {1..1000000}\ c$'\n' >file

real    0m1.44s
user    0m1.28s
sys     0m0.06s
ksh$ time echo -n a\ {1..1000000}\ c$'\n' | sed "s/^ //" >file

real    0m2.38s
user    0m1.52s
sys     0m0.14s

ありがとう...その最後のksh例は、私が期待したものに沿っています
...-Peter.O
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.