bahamat và Alan Curry có quyền: điều này là do cách vỏ của bạn đệm đầu ra echo
. Cụ thể, shell của bạn là bash và nó phát ra một write
cuộc gọi hệ thống trên mỗi dòng. Do đó đoạn mã thứ nhất thực hiện ghi 1000000 vào tệp đĩa, trong khi đoạn mã thứ hai tạo 1000000 ghi vào đường ống và sed (phần lớn song song, nếu bạn có nhiều CPU) sẽ tạo ra số lượng ghi nhỏ hơn đáng kể vào tệp đĩa do đầu ra của nó đệm.
Bạn có thể quan sát những gì đang xảy ra bằng cách chạy 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) ---
Các shell khác như ksh đệm đầu ra echo
ngay cả khi nó là multiline, vì vậy bạn sẽ không thấy nhiều sự khác biệt.
$ 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
Với bash tôi nhận được tỷ lệ thời gian tương tự. Với ksh tôi thấy đoạn mã thứ hai chạy chậm hơn.
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