Để tôi lấy một ví dụ:
$ timeout 1 yes "GNU" > file1
$ wc -l file1
11504640 file1
$ for ((sec0=`date +%S`;sec<=$(($sec0+5));sec=`date +%S`)); do echo "GNU" >> file2; done
$ wc -l file2
1953 file2
Ở đây bạn có thể thấy rằng lệnh yesviết 11504640các dòng trong một giây trong khi tôi chỉ có thể viết 1953các dòng trong 5 giây bằng cách sử dụng bash's forvà echo.
Như được đề xuất trong các bình luận, có nhiều thủ thuật khác nhau để làm cho nó hiệu quả hơn nhưng không có cách nào phù hợp với tốc độ của yes:
$ ( while :; do echo "GNU" >> file3; done) & pid=$! ; sleep 1 ; kill $pid
[1] 3054
$ wc -l file3
19596 file3
$ timeout 1 bash -c 'while true; do echo "GNU" >> file4; done'
$ wc -l file4
18912 file4
Chúng có thể viết tới 20 nghìn dòng trong một giây. Và chúng có thể được cải thiện hơn nữa để:
$ timeout 1 bash -c 'while true; do echo "GNU"; done >> file5'
$ wc -l file5
34517 file5
$ ( while :; do echo "GNU"; done >> file6 ) & pid=$! ; sleep 1 ; kill $pid
[1] 5690
$ wc -l file6
40961 file6
Những thứ này giúp chúng tôi có tới 40 nghìn dòng trong một giây. Tốt hơn, nhưng vẫn còn rất xa yesđể có thể viết khoảng 11 triệu dòng trong một giây!
Vì vậy, làm thế nào để yesviết vào tập tin nhanh như vậy?
datecó phần nặng, cộng với trình bao phải mở lại luồng đầu ra echocho mỗi lần lặp. Trong ví dụ đầu tiên, chỉ có một lệnh gọi duy nhất với một chuyển hướng đầu ra duy nhất và lệnh cực kỳ nhẹ. Hai là không có cách nào so sánh được.
datecó thể nặng, xem chỉnh sửa câu hỏi của tôi.
timeout 1 $(while true; do echo "GNU">>file2; done;)là cách sử dụng sai timeout vì timeoutlệnh sẽ chỉ bắt đầu sau khi thay thế lệnh kết thúc. Sử dụng timeout 1 sh -c 'while true; do echo "GNU">>file2; done'.
write(2)các cuộc gọi hệ thống, không phải tải thuyền của các tòa nhà khác, trên đầu hoặc thậm chí tạo quy trình trong ví dụ đầu tiên của bạn (chạy và chờ datecho mỗi dòng được in vào tệp). Một giây viết chỉ đủ để nó bị nghẽn cổ chai trên đĩa I / O (chứ không phải CPU / bộ nhớ), trên một hệ thống hiện đại có nhiều RAM. Nếu được phép chạy lâu hơn, sự khác biệt sẽ nhỏ hơn. (Tùy thuộc vào mức độ thực thi bash mà bạn sử dụng và tốc độ tương đối của CPU và đĩa, bạn thậm chí có thể không bão hòa I / O đĩa với bash).