Bahamat und Alan Curry haben Recht: Dies liegt an der Art und Weise, wie Ihre Shell die Ausgabe von puffert echo
. Insbesondere handelt es sich bei Ihrer Shell um eine Bash-Shell, die einen write
Systemaufruf pro Zeile ausgibt . Daher schreibt das erste Snippet 1000000 in eine Festplattendatei, während das zweite Snippet 1000000 in eine Pipe schreibt und sed (bei mehreren CPUs weitgehend parallel) aufgrund seiner Ausgabe eine erheblich geringere Anzahl von Schreibvorgängen in eine Festplattendatei durchführt Pufferung.
Sie können beobachten , was durch Laufen ist los 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) ---
Andere Shells wie ksh puffern die Ausgabe echo
auch dann, wenn sie mehrzeilig ist, sodass Sie keinen großen Unterschied feststellen können.
$ 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
Mit Bash bekomme ich ähnliche Timing-Verhältnisse. Mit ksh sehe ich das zweite Snippet langsamer laufen.
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