SORU
4 EKİM 2010, PAZARTESİ


Neden stdout baskı bu kadar yavaş? Hızlandırdı olabilir mi?

Her zaman/sadece bir yazdırma deyimi ile terminal çıkış için ne kadar sürer ile sinirli hayret ettik. Bazı yeni acı yavaş giriş yaptıktan sonra bunu araştırmaya karar verdim ve neredeyse bulmak oldukça şaşırdıtümzaman harcanan terminal için sonuçlar bekliyor.

Stdout yazmak bir şekilde hızlandırdı olabilir?

Komut ('print_timer.py' Bu soru altında) 100 k hatları stdout yazarken zamanlama karşılaştırmak için, dosya ve stdout /dev/null yönlendirilir. yazdım Burada zamanlama sonucu:

$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 be. Python /dev/null falan stdout ben yeniden tanıma gibi perde arkasında bir şey yapmıyor emin olmak için, komut dosyası dışında yönlendirme 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

Python bu bir hile değil, sadece terminal. Ben her zaman //null dev damping çıkış olayları hızlandırdım, ama asla bunun önemli olduğunu düşündüm biliyordu!

Tty nasıl beni şaşırtıyor. Nasıl olabilir bu yazı için fiziksel disk var daha hızlı yazmak için "ekran" (muhtemelen bir RAM op) ve etkili bir şekilde hızlı olarak sadece damping, çöp ile /dev/null?

This link böylece terminal I/O bloğu nasıl bahsediyor< . em ^"[giriş] ayrıştırma, Kare tampon güncelleme, pencere kaydırmak için X sunucu ile iletişim kurmak ve böylece"... ama tam olarak anlamıyorum. Bu kadar uzun süren ne olabilir?

Çıkış (kısa daha hızlı bir tty uygulanması? yok bekliyorum ama yine de sorayım dedim.


GÜNCELLEME: bazı yorumları okuduktan sonra ne kadar ekran boyutu aslında baskı zamanı var merak ettim, ve bir önemi var. Gerçekten yavaş rakamların üstünde Gnome benim terminal 1920x1200 havaya uçuruldu. Eğer çok küçük ben azaltmak istiyorum

-----
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 benim sorum değiştirmez. Sadeceeklerterminal ekranı oluşturma Bir Uygulama yazma stdout yavaşlatır anlamıyorum neden benim soru. Neden benim program ekran için işleme devam etmek için beklemek gerekiyor mu?

Tüm terminal/tty uygulamalar değil eşit yaratılmıştır? Deney daha var. Gerçekten bana öyle geliyor ki gibi bir terminal gerekir arabellek gelen tüm verileri ayrıştırılamadı/hale görünmez ve sadece render en son Kırılan görünür halde mevcut ekran yapılandırması mantıklı bir çerçeve oranı. Eğer öyleyse yazabilirim fsync disk ~0.1 saniye, bir terminal olabilir tam aynı operasyonda şeyler için (belki bir kaç ekran güncellemeleri sırasında yaptı.

Hala uygulama tarafında bu davranış programcı için daha iyi yapmak için değiştirilebilir tty ayarı vardır umuyorum. Eğer bu terminal uygulaması bir sorun ise kesinlikle, o zaman bu belki StackOverflow üzerinde ait değil miydi?

Neyi kaçırıyorum?


Burada python programı zamanlama oluşturmak için kullanılır:

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

CEVAP
4 EKİM 2010, PAZARTESİ


Nasıl olabilir bu yazı için fiziksel disk var daha hızlı yazmak için "ekran" (muhtemelen bir RAM op) ve etkili bir şekilde hızlı olarak sadece damping, çöp ile /dev/null?

Tebrik ederim, G/Ç arabelleği önemini keşfettim. :-)

Diskgörünüryüksek tamponlu olduğundan daha hızlı olması için: write() çağrıları bir şey aslında fiziksel diske yazılmadan önce dönen tüm Python. (OS sonra bu, tek tek binlerce büyük, verimli bir boyutta yazar birçok birleştirerek yapar.)

Terminal, diğer yandan, çok az veya hiç tampon yapar: 9* / write(line) *Bu bekler her bireytamtam yazmak (yani çıkış aygıtı için ekran).

Karşılaştırmanın adil olması için, dosya testi için örnek değiştirerek yapabilirsiniz hangi terminali, tampon olarak aynı çıkışı kullanmak gerekir:

fp = file("out.txt", "w", 1)   # line-buffered, like stdout
[...]
for x in range(lineCount):
    fp.write(line)
    os.fsync(fp.fileno())      # wait for the write to actually complete

Tampon benim makinede ve dosya yazma testi de burada 100,000 hatları için 0.05 s yaptım.

Yukarıdaki değişiklikler olmakta, yazmak ile ancak 40 saniye diske sadece 1000 satır yazmak için alır. 100,000 hatları bekliyor yazmak için verdim, ama daha önceki hesaba katarsak, sürerbir saatten fazla.

Bu perspektif içine terminal 11 saniye koyuyor, değil mi?

Yani cevap sizin özgün soru, yazılı bir terminal aslında cayır cayır yanan hızlı, her şey düşünüldü, ve orada olmayan bir sürü oda yapmak çok daha hızlı (ama bireysel terminalleri farklıdır, ne kadar çalışıyorlar, Russ yorum bu cevap).

(Daha fazla tamponlama yazmak gibi g/Ç disk ekleyebilirsiniz, ama sonra tampon kızarmış alır bitene kadar terminal için yazılmış ne olduğunu görmek istemezsin. Bir anlaşma var: karşı toplu verimliliği etkileşim.)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • NightShader1

    NightShader1

    25 Temmuz 2006
  • RD

    RD

    19 NİSAN 2006
  • TROPFEST

    TROPFEST

    27 Mart 2007