以下の例は私を驚かせました。直感に反しているようです... echo | sed
コンボに対して、ひげがさらにユーザー時間あるという事実は別として。
echo
が単独で実行されているのになぜそんなに多くを使用しているのですかsys time、または質問は、sed
はどのようにプレイの状態を変更するのですか? echo
は同じようにする必要があるようです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
bahamatとAlanCurryは正しいです。これは、シェルがecho
の出力をバッファリングする方法によるものです。具体的には、シェルはbashであり、1行につき1つのwrite
システムコールを発行します。したがって、最初のスニペットはディスクファイルに1000000回の書き込みを行いますが、2番目のスニペットはパイプに1000000回の書き込みを行い、sed(複数のCPUがある場合はほぼ並行して)は、出力のためにディスクファイルへの書き込み回数を大幅に減らします。バッファリング。
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