Tôi luôn luôn ngạc nhiên / thất vọng với việc mất bao lâu để đơn giản xuất ra thiết bị đầu cuối với một câu lệnh in. Sau một số lần đăng nhập chậm chạp gần đây, tôi quyết định xem xét nó và khá ngạc nhiên khi thấy rằng gần như toàn bộ thời gian đang chờ đợi thiết bị đầu cuối xử lý kết quả.
Có thể viết để stdout được tăng tốc bằng cách nào đó?
Tôi đã viết một tập lệnh (' print_timer.py
' ở cuối câu hỏi này) để so sánh thời gian khi viết các dòng 100k vào thiết bị xuất chuẩn, vào tệp và với thiết bị xuất chuẩn được chuyển hướng đến /dev/null
. Đây là kết quả thời gian:
$ 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
Ồ Để chắc chắn rằng trăn không làm gì đó đằng sau hậu trường như nhận ra rằng tôi đã gán lại thiết bị xuất chuẩn thành / dev / null hoặc thứ gì đó, tôi đã chuyển hướng bên ngoài kịch bản ...
$ 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
Vì vậy, nó không phải là một trò lừa trăn, nó chỉ là thiết bị đầu cuối. Tôi luôn biết đầu ra bán phá giá cho / dev / null tăng tốc mọi thứ, nhưng không bao giờ nghĩ rằng nó là đáng kể!
Nó làm tôi ngạc nhiên khi tty chậm như thế nào. Làm thế nào có thể ghi vào đĩa vật lý là CÁCH nhanh hơn ghi vào "màn hình" (có lẽ là op toàn bộ RAM), và có hiệu quả nhanh như chỉ đơn giản là đổ rác vào / dev / null?
Liên kết này nói về cách thiết bị đầu cuối sẽ chặn I / O để nó có thể "phân tích [đầu vào], cập nhật bộ đệm khung, giao tiếp với máy chủ X để cuộn cửa sổ, v.v." nhưng tôi không hoàn toàn có được nó Điều gì có thể mất nhiều thời gian?
Tôi hy vọng không có lối thoát nào (thiếu việc triển khai nhanh hơn?) Nhưng dù sao tôi cũng sẽ hỏi.
CẬP NHẬT: sau khi đọc một số bình luận, tôi tự hỏi kích thước màn hình của tôi thực sự ảnh hưởng đến thời gian in như thế nào và nó có một số ý nghĩa quan trọng. Những con số thực sự chậm ở trên là với thiết bị đầu cuối Gnome của tôi được thổi lên tới 1920x1200. Nếu tôi giảm nó rất nhỏ, tôi sẽ ...
-----
timing summary (100k lines each)
-----
print : 2.920 s
write to file (+fsync) : 0.121 s
print with stdout = /dev/null : 0.048 s
Điều đó chắc chắn tốt hơn (~ 4x), nhưng không thay đổi câu hỏi của tôi. Nó chỉ thêm vào câu hỏi của tôi vì tôi không hiểu tại sao kết xuất màn hình đầu cuối sẽ làm chậm ứng dụng ghi vào thiết bị xuất chuẩn. Tại sao chương trình của tôi cần đợi kết xuất màn hình tiếp tục?
Có phải tất cả các ứng dụng đầu cuối / tty không được tạo ra bằng nhau? Tôi vẫn chưa thử nghiệm. Tôi thực sự có vẻ như một thiết bị đầu cuối có thể đệm tất cả dữ liệu đến, phân tích / kết xuất nó một cách vô hình và chỉ hiển thị đoạn dữ liệu gần đây nhất có thể nhìn thấy trong cấu hình màn hình hiện tại ở tốc độ khung hình hợp lý. Vì vậy, nếu tôi có thể ghi + fsync vào đĩa trong ~ 0,1 giây, một thiết bị đầu cuối sẽ có thể hoàn thành thao tác tương tự theo thứ tự đó (có thể là một vài cập nhật màn hình trong khi nó đã thực hiện).
Tôi vẫn hy vọng có một cài đặt tty có thể được thay đổi từ phía ứng dụng để làm cho hành vi này tốt hơn cho lập trình viên. Nếu đây thực sự là một sự cố ứng dụng đầu cuối, thì điều này thậm chí có thể không thuộc về StackOverflow?
Tôi đang thiếu gì?
Đây là chương trình python được sử dụng để tạo thời gian:
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