bahamat ve Alan Curry'de haklılar: bunun nedeni kabuğunuzun çıkışını tamponlamasıdır echo
. Spesifik olarak, kabuğunuz bash ve write
her satıra bir sistem çağrısı yapar. Bu nedenle, birinci snippet 1000000'lük bir disk dosyasına yazma yapar, ikinci snippet 1000000'lük bir boruya yazma yapar ve sed (büyük ölçüde paralel olarak, eğer birden fazla CPU'nuz varsa) çıkışından dolayı bir disk dosyasına çok daha az sayıda yazma yapar tamponlama.
Strace koşarak neler olduğunu gözlemleyebilirsiniz .
$ 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 gibi diğer mermiler echo
, multiline olsa bile çıktısını tamponlar , böylece fazla bir fark görmezsiniz.
$ 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 ile benzer zamanlama oranları olsun. Ksh ile ikinci snippet'in daha yavaş çalıştığını görüyorum.
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