ขอยกตัวอย่าง:
$ 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
ที่นี่คุณสามารถเห็นได้ว่าคำสั่งyesเขียน11504640เส้นในครั้งที่สองในขณะที่ฉันสามารถเขียนเพียง1953บรรทัดใน 5 วินาทีโดยใช้ทุบตีของและforecho
ตามที่แนะนำในข้อคิดเห็นมีเทคนิคต่าง ๆ เพื่อให้มีประสิทธิภาพมากขึ้น แต่ไม่มีใครเข้ามาใกล้เคียงกับความเร็วของ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
สิ่งเหล่านี้สามารถเขียนได้มากถึง 20,000 บรรทัดในหนึ่งวินาที และพวกเขาสามารถปรับปรุงเพิ่มเติมเพื่อ:
$ 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
สิ่งเหล่านี้ทำให้เราได้มากถึง 40,000 บรรทัดในไม่กี่วินาที ดีกว่า แต่ก็ยังเป็นหนทางไกลyesที่สามารถเขียนได้ 11 ล้านบรรทัดในหนึ่งวินาที!
ดังนั้นการyesเขียนไปยังไฟล์อย่างรวดเร็วได้อย่างไร
dateค่อนข้างหนักและเปลือกต้องเปิดกระแสข้อมูลขาออกใหม่สำหรับechoการวนซ้ำทุกครั้ง ในตัวอย่างแรกมีเพียงการเรียกใช้คำสั่งเดียวด้วยการเปลี่ยนเส้นทางเอาต์พุตเดียวและคำสั่งนั้นมีน้ำหนักเบามาก ทั้งสองไม่มีทางเปรียบเทียบกันได้
dateอาจจะมีน้ำหนักมากให้ดูที่การแก้ไขคำถามของฉัน
timeout 1 $(while true; do echo "GNU">>file2; done;)เป็นวิธีที่ไม่ถูกต้องที่จะใช้timeout เนื่องจากtimeoutคำสั่งจะเริ่มต้นเมื่อการแทนที่คำสั่งเสร็จสิ้น timeout 1 sh -c 'while true; do echo "GNU">>file2; done'ใช้
write(2)เรียกระบบไม่ใช่บน boatloads ของ syscalls อื่น ๆ โอเวอร์เฮดของเชลล์หรือแม้แต่การสร้างกระบวนการในตัวอย่างแรกของคุณ (ซึ่งจะทำงานและรอdateให้ทุกบรรทัดที่พิมพ์ไปยังไฟล์) หนึ่งวินาทีของการเขียนนั้นเพียงพอที่จะทำให้เกิดปัญหาคอขวดบนดิสก์ I / O (แทนที่จะเป็น CPU / หน่วยความจำ) ในระบบที่ทันสมัยพร้อม RAM จำนวนมาก หากอนุญาตให้ทำงานได้นานกว่าความแตกต่างก็จะเล็กลง (ขึ้นอยู่กับว่าการใช้ bash นั้นแย่เพียงใดและความเร็วที่สัมพันธ์กันของ CPU และดิสก์คุณอาจไม่ได้ใช้ I / O ของดิสก์ที่อิ่มตัวด้วย bash)