ขอยกตัวอย่าง:
$ 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 วินาทีโดยใช้ทุบตีของและfor
echo
ตามที่แนะนำในข้อคิดเห็นมีเทคนิคต่าง ๆ เพื่อให้มีประสิทธิภาพมากขึ้น แต่ไม่มีใครเข้ามาใกล้เคียงกับความเร็วของ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)