ฉันประหลาดใจ / ผิดหวังอยู่เสมอว่าต้องใช้เวลานานแค่ไหนในการส่งออกไปยังเครื่องด้วยคำสั่งพิมพ์ หลังจากการบันทึกอย่างช้า ๆ เมื่อเร็ว ๆ นี้ฉันตัดสินใจที่จะมองมันและรู้สึกประหลาดใจมากที่พบว่าเกือบตลอดเวลาที่ใช้รอเครื่องเทอร์มินัลเพื่อประมวลผลผลลัพธ์
การเขียนไปยัง stdout สามารถเร่งความเร็วได้บ้าง
ผมเขียนสคริปต์ (' print_timer.py
' ที่ด้านล่างของคำถามนี้) เพื่อเปรียบเทียบระยะเวลาเมื่อเขียน 100k เส้นที่ stdout /dev/null
เพื่อไฟล์และมีการเปลี่ยนเส้นทางไปยัง นี่คือผลการจับเวลา:
$ python print_timer.py
this is a test
this is a test
<snipped 99997 lines>
this is a test
-----
timing summary (100k lines each)
-----
print :11.950 s
write to file (+ fsync) : 0.122 s
print with stdout = /dev/null : 0.050 s
ว้าว. เพื่อให้แน่ใจว่าไพ ธ อนไม่ได้ทำอะไรบางอย่างอยู่เบื้องหลังเช่นตระหนักว่าฉันกำหนด stdout ใหม่ให้กับ / dev / null หรือบางอย่างฉันเปลี่ยนเส้นทางนอกสคริปต์ ...
$ python print_timer.py > /dev/null
-----
timing summary (100k lines each)
-----
print : 0.053 s
write to file (+fsync) : 0.108 s
print with stdout = /dev/null : 0.045 s
ดังนั้นจึงไม่ใช่เคล็ดลับหลามมันเป็นเพียงเทอร์มินัล ฉันมักจะรู้ว่าการทิ้งเอาท์พุทไปยัง / dev / null เร่งสิ่งต่างๆ แต่ไม่เคยคิดว่ามันสำคัญมาก!
มันทำให้ฉันประหลาดใจว่า tty นั้นช้าแค่ไหน เป็นไปได้อย่างไรที่การเขียนไปยังดิสก์ทางกายภาพนั้นเป็นวิธีที่เร็วกว่าการเขียนไปที่ "หน้าจอ" (สันนิษฐานว่าเป็น all-RAM op) และมีความรวดเร็วพอ ๆ กับการทิ้งขยะโดยใช้ / dev / null?
ลิงค์นี้พูดถึงว่าเทอร์มินัลจะบล็อก I / O อย่างไรจึงจะสามารถ"แยก [อินพุต] อัปเดตเฟรมบัฟเฟอร์สื่อสารกับเซิร์ฟเวอร์ X เพื่อเลื่อนหน้าต่างและอื่น ๆ " ... แต่ฉันไม่ รับอย่างเต็มที่มัน สิ่งที่ใช้เวลานาน
ฉันคาดหวังว่าจะไม่มีทางออก (สั้นจากการใช้ tty ที่เร็วขึ้น?) แต่รูปที่ฉันถามอยู่แล้ว
UPDATE: หลังจากอ่านความคิดเห็นฉันสงสัยว่าขนาดหน้าจอของฉันมีผลต่อเวลาพิมพ์จริงแค่ไหนและมันก็มีความสำคัญ ตัวเลขที่ช้ามาก ๆ ข้างต้นนั้นคือเครื่องของฉัน Gnome ที่เป่าได้ถึง 1920x1200 ถ้าฉันลดมันให้เล็กลงฉันจะได้ ...
-----
timing summary (100k lines each)
-----
print : 2.920 s
write to file (+fsync) : 0.121 s
print with stdout = /dev/null : 0.048 s
แน่นอนว่าจะดีกว่า (~ 4x) แต่ไม่เปลี่ยนคำถามของฉัน มันเพิ่มคำถามของฉันเท่านั้นเพราะฉันไม่เข้าใจว่าทำไมการเรนเดอร์หน้าจอเทอร์มินัลควรทำให้แอปพลิเคชันเขียนช้าลง ทำไมโปรแกรมของฉันต้องรอให้การเรนเดอร์หน้าจอดำเนินการต่อ
แอปเทอร์มินัล / tty ทั้งหมดไม่ถูกสร้างขึ้นเท่ากันหรือไม่? ฉันยังไม่ได้ทดลอง สำหรับฉันแล้วดูเหมือนว่าเทอร์มินัลควรจะสามารถบัฟเฟอร์ข้อมูลที่เข้ามาทั้งหมดแยกวิเคราะห์ / แสดงผลอย่างล่องหนและแสดงเฉพาะชิ้นล่าสุดที่ปรากฏในการกำหนดค่าหน้าจอปัจจุบันที่อัตราเฟรมที่สมเหตุสมผล ดังนั้นถ้าฉันสามารถเขียน + fsync ลงในดิสก์ได้ในเวลา ~ 0.1 วินาทีเทอร์มินัลควรจะสามารถทำการดำเนินการเดียวกันให้เสร็จสมบูรณ์ตามลำดับนั้น (อาจมีการปรับปรุงหน้าจอเล็กน้อยในขณะที่ทำ)
ฉันยังคงหวังว่าจะมีการตั้งค่า tty ที่สามารถเปลี่ยนได้จากด้านแอปพลิเคชันเพื่อให้พฤติกรรมนี้ดีขึ้นสำหรับโปรแกรมเมอร์ หากนี่เป็นปัญหาของแอปพลิเคชันเทอร์มินัลอย่างเคร่งครัดนี่อาจจะไม่ได้อยู่ใน StackOverflow ใช่ไหม
ฉันพลาดอะไรไป
นี่คือโปรแกรมไพ ธ อนที่ใช้สร้างช่วงเวลา:
import time, sys, tty
import os
lineCount = 100000
line = "this is a test"
summary = ""
cmd = "print"
startTime_s = time.time()
for x in range(lineCount):
print line
t = time.time() - startTime_s
summary += "%-30s:%6.3f s\n" % (cmd, t)
#Add a newline to match line outputs above...
line += "\n"
cmd = "write to file (+fsync)"
fp = file("out.txt", "w")
startTime_s = time.time()
for x in range(lineCount):
fp.write(line)
os.fsync(fp.fileno())
t = time.time() - startTime_s
summary += "%-30s:%6.3f s\n" % (cmd, t)
cmd = "print with stdout = /dev/null"
sys.stdout = file(os.devnull, "w")
startTime_s = time.time()
for x in range(lineCount):
fp.write(line)
t = time.time() - startTime_s
summary += "%-30s:%6.3f s\n" % (cmd, t)
print >> sys.stderr, "-----"
print >> sys.stderr, "timing summary (100k lines each)"
print >> sys.stderr, "-----"
print >> sys.stderr, summary