Sự khác biệt giữa | và << ()?
Có một sự khác biệt giữa chúng:
Đối với hai câu hỏi tiếp theo, chúng tôi sẽ làm một số strace
:
pipe
:
$ strace -fc bash -c 'tac /usr/share/dict/american-english | grep qwerty'
$ time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.008120 2707 3 1 wait4
0.00 0.000000 0 352 read
0.00 0.000000 0 229 write
0.00 0.000000 0 20 2 open
0.00 0.000000 0 29 2 close
0.00 0.000000 0 40 17 stat
0.00 0.000000 0 19 fstat
0.00 0.000000 0 117 lseek
0.00 0.000000 0 38 mmap
0.00 0.000000 0 18 mprotect
0.00 0.000000 0 6 munmap
0.00 0.000000 0 25 brk
0.00 0.000000 0 22 rt_sigaction
0.00 0.000000 0 18 rt_sigprocmask
0.00 0.000000 0 1 rt_sigreturn
0.00 0.000000 0 3 2 ioctl
0.00 0.000000 0 24 12 access
0.00 0.000000 0 1 pipe
0.00 0.000000 0 2 dup2
0.00 0.000000 0 1 getpid
0.00 0.000000 0 1 1 getpeername
0.00 0.000000 0 2 clone
0.00 0.000000 0 3 execve
0.00 0.000000 0 1 uname
0.00 0.000000 0 1 getrlimit
0.00 0.000000 0 13 getuid
0.00 0.000000 0 13 getgid
0.00 0.000000 0 13 geteuid
0.00 0.000000 0 13 getegid
0.00 0.000000 0 1 getppid
0.00 0.000000 0 1 getpgrp
0.00 0.000000 0 3 arch_prctl
0.00 0.000000 0 1 time
------ ----------- ----------- --------- --------- ----------------
100.00 0.008120 1034 37 total
Process Substitution
:
$ strace -fc bash -c 'grep qwerty < <(tac /usr/share/dict/american-english)'
$ time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
99.14 0.016001 4000 4 2 wait4
0.46 0.000075 0 229 write
0.24 0.000038 0 341 read
0.16 0.000026 1 24 brk
0.00 0.000000 0 21 2 open
0.00 0.000000 0 27 close
0.00 0.000000 0 40 17 stat
0.00 0.000000 0 19 fstat
0.00 0.000000 0 117 lseek
0.00 0.000000 0 38 mmap
0.00 0.000000 0 18 mprotect
0.00 0.000000 0 6 munmap
0.00 0.000000 0 35 rt_sigaction
0.00 0.000000 0 24 rt_sigprocmask
0.00 0.000000 0 2 rt_sigreturn
0.00 0.000000 0 3 2 ioctl
0.00 0.000000 0 24 12 access
0.00 0.000000 0 1 pipe
0.00 0.000000 0 3 dup2
0.00 0.000000 0 1 getpid
0.00 0.000000 0 1 1 getpeername
0.00 0.000000 0 3 clone
0.00 0.000000 0 3 execve
0.00 0.000000 0 1 uname
0.00 0.000000 0 1 1 fcntl
0.00 0.000000 0 2 getrlimit
0.00 0.000000 0 13 getuid
0.00 0.000000 0 13 getgid
0.00 0.000000 0 13 geteuid
0.00 0.000000 0 13 getegid
0.00 0.000000 0 1 getppid
0.00 0.000000 0 1 getpgrp
0.00 0.000000 0 3 arch_prctl
0.00 0.000000 0 1 time
------ ----------- ----------- --------- --------- ----------------
100.00 0.016140 1046 37 total
Tại sao một cái gì đó nhanh hơn so với khác?
Và cái gì thực sự nhanh hơn?
Bạn có thể thấy, process substitution
chậm hơn pipe
trong trường hợp này, vì nó sử dụng nhiều cuộc gọi hệ thống hơn. Cả hai đều dành nhiều thời gian để chờ đợi các tiến trình con, nhưng process substitution
sử dụng nhiều wait4()
tòa nhà hơn và sử dụng nhiều thời gian hơn cho mỗi cuộc gọi hơn pipe
.
Tại sao không ai đề nghị xargs?
Tôi không nghĩ xargs
có thể giúp được gì ở đây, đây không phải là công việc của nó.
Cập nhật
Như đề xuất của @ Gilles, tôi thực hiện kiểm tra với tệp lớn hơn, 2GB dữ liệu ngẫu nhiên được tạo từ /dev/urandom
. Nó cho thấy rằng pipe
thực sự nhanh hơn process substitution
.
pipe
:
$ strace -fc bash -c 'tac sample.txt | grep qwerty'
$ time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
81.15 8.284959 2761653 3 1 wait4
17.89 1.825959 2 780959 read
0.91 0.092708 0 524286 write
0.05 0.005364 0 262146 lseek
0.00 0.000000 0 20 2 open
0.00 0.000000 0 29 2 close
0.00 0.000000 0 40 17 stat
0.00 0.000000 0 19 fstat
0.00 0.000000 0 38 mmap
0.00 0.000000 0 18 mprotect
0.00 0.000000 0 6 munmap
0.00 0.000000 0 25 brk
0.00 0.000000 0 22 rt_sigaction
0.00 0.000000 0 18 rt_sigprocmask
0.00 0.000000 0 1 rt_sigreturn
0.00 0.000000 0 3 2 ioctl
0.00 0.000000 0 24 12 access
0.00 0.000000 0 1 pipe
0.00 0.000000 0 2 dup2
0.00 0.000000 0 1 getpid
0.00 0.000000 0 1 1 getpeername
0.00 0.000000 0 2 clone
0.00 0.000000 0 3 execve
0.00 0.000000 0 1 uname
0.00 0.000000 0 1 getrlimit
0.00 0.000000 0 13 getuid
0.00 0.000000 0 13 getgid
0.00 0.000000 0 13 geteuid
0.00 0.000000 0 13 getegid
0.00 0.000000 0 1 getppid
0.00 0.000000 0 1 getpgrp
0.00 0.000000 0 3 arch_prctl
0.00 0.000000 0 1 time
------ ----------- ----------- --------- --------- ----------------
100.00 10.208990 1567727 37 total
process substitution
:
$ strace -fc bash -c 'grep qwerty < <(tac sample.txt)'
$ time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
99.51 13.912869 3478217 4 2 wait4
0.38 0.053373 0 655269 read
0.09 0.013084 0 524286 write
0.02 0.002454 0 262146 lseek
0.00 0.000030 1 38 mmap
0.00 0.000024 1 24 12 access
0.00 0.000000 0 21 2 open
0.00 0.000000 0 27 close
0.00 0.000000 0 40 17 stat
0.00 0.000000 0 19 fstat
0.00 0.000000 0 18 mprotect
0.00 0.000000 0 6 munmap
0.00 0.000000 0 24 brk
0.00 0.000000 0 35 rt_sigaction
0.00 0.000000 0 24 rt_sigprocmask
0.00 0.000000 0 2 rt_sigreturn
0.00 0.000000 0 3 2 ioctl
0.00 0.000000 0 1 pipe
0.00 0.000000 0 3 dup2
0.00 0.000000 0 1 getpid
0.00 0.000000 0 1 1 getpeername
0.00 0.000000 0 3 clone
0.00 0.000000 0 3 execve
0.00 0.000000 0 1 uname
0.00 0.000000 0 1 1 fcntl
0.00 0.000000 0 2 getrlimit
0.00 0.000000 0 13 getuid
0.00 0.000000 0 13 getgid
0.00 0.000000 0 13 geteuid
0.00 0.000000 0 13 getegid
0.00 0.000000 0 1 getppid
0.00 0.000000 0 1 getpgrp
0.00 0.000000 0 3 arch_prctl
0.00 0.000000 0 1 time
------ ----------- ----------- --------- --------- ----------------
100.00 13.981834 1442060 37 total
< <(...)
viết tắt của0< <(...)
, không<<(...)
.