Ben her zaman bir baskı bildirimi ile terminal çıktı için ne kadar sürer ile şaşırdım / hayal kırıklığına uğradım. Son zamanlarda ağrılı yavaş oturum açtıktan sonra buna bakmaya karar verdim ve harcanan neredeyse tüm zamanların terminalin sonuçları işlemesini beklediğini bulmak oldukça şaşırdı .
Stdout'a yazmak bir şekilde hızlandırılabilir mi?
print_timer.py
100k satır stdout, dosya ve stdout yönlendirilen ile yazarken zamanlamayı karşılaştırmak için bir komut dosyası ( bu sorunun altında ' ') yazdım /dev/null
. Zamanlama sonucu şöyledir:
$ 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
Vay. Python'un stdout'u / dev / null veya başka bir şeye yeniden atadığımı fark etmek gibi perde arkasında bir şey yapmadığından emin olmak için, komut dosyasının dışındaki yönlendirmeyi yaptım ...
$ 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
Yani bir python hilesi değil, sadece terminal. Ben her zaman / dev / null hızlandırmak şeyler damping çıktı biliyordum, ama asla bu önemli olduğunu anladım!
Tty'nin ne kadar yavaş olduğu beni şaşırtıyor. Nasıl fiziksel diske yazmak "ekrana" (muhtemelen bir tüm-RAM op) yazmaktan daha hızlı ve etkili bir şekilde / dev / null ile çöp dökümü kadar hızlı olabilir?
Bu bağlantı , terminalin G / Ç'yi nasıl engelleyeceğini açıklar, böylece pencereyi kaydırmak için "girişi" ayrıştırabilir, çerçeve arabelleğini güncelleyebilir, X sunucusuyla iletişim kurabilir " ... tamamen olsun. Ne bu kadar uzun sürebilir?
Ben hiçbir çıkış yolu (daha hızlı tty uygulama kısa?) Bekliyoruz ama yine de soracağım rakam.
GÜNCELLEME: bazı yorumları okuduktan sonra ekran boyutumun baskı süresi üzerinde gerçekte ne kadar etkisi olduğunu merak ettim ve bunun bir önemi var. Yukarıdaki gerçekten yavaş sayılar Gnome terminalim 1920x1200'e kadar şişmiş durumda. Çok küçük düşürürsem ...
-----
timing summary (100k lines each)
-----
print : 2.920 s
write to file (+fsync) : 0.121 s
print with stdout = /dev/null : 0.048 s
Bu kesinlikle daha iyi (~ 4x), ama sorumu değiştirmiyor. Terminal ekran oluşturma neden bir uygulama yazma stdout yavaşlatmak anlamıyorum çünkü sadece benim soruya ekler . Programımın ekran görüntülemenin devam etmesini neden beklemesi gerekiyor?
Tüm terminal / tty uygulamaları eşit oluşturulmamış mı? Henüz denemedim. Gerçekten bir terminalin tüm gelen verileri arabelleğe alması, görünmez bir şekilde ayrıştırması / işlemesi ve yalnızca geçerli ekran yapılandırmasında görünür olan en yeni yığını makul bir kare hızında oluşturması gerektiği gibi görünüyor. Bu yüzden ~ 0.1 saniye içinde diske + fsync yazabilirsem, bir terminal aynı işlemi o sırayla tamamlayabilmelidir (bunu yaparken birkaç ekran güncellemesiyle).
Hala bu tarafı programcı için daha iyi hale getirmek için uygulama tarafından değiştirilebilen bir tty ayarı olduğunu umuyorum. Bu kesinlikle bir terminal uygulaması sorunu ise, o zaman bu bile StackOverflow ait değil?
Neyi kaçırıyorum?
İşte zamanlamayı oluşturmak için kullanılan python programı:
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