2010-06-23 19 views
9

Yeni satır yazdırmak neden bu kadar uzun sürüyor? Bu sadece makinem mi yoksa başkaları da aynı etkiyi görüyor mu? yeni satır ilePerl'de " n" yazdırmak neden bu kadar uzun sürüyor?

:

#!/usr/bin/perl 

use strict; 
use Benchmark; 

    timethis(100000,'main();'); 


    sub main { 
     print "you are the bomb. \n"; 
    } 


    # outputs: 
    # timethis 100000: 8 wallclock secs (0.15 usr + 0.45 sys = 0.60 CPU) @ 166666.67/s (n=100000) 

W/yeni satır O:

#!/usr/bin/perl 

use strict; 
use Benchmark; 

    timethis(100000,'main();'); 


    sub main { 
     print "you are the bomb. "; 
    } 


    # outputs: 
    # timethis 100000: 0 wallclock secs (0.09 usr + 0.04 sys = 0.13 CPU) @ 769230.77/s (n=100000) 
    #  (warning: too few iterations for a reliable count) 

Düzenleme: de iki yerleştirme "\ n" yürütme neden olduğu eklemek istiyorum 'u en az iki kez, en azından wallclock saniye almak için.

timethis 100000: 16 wallclock secs (0.15 usr + 0.52 sys = 0.67 CPU) @ 149253.73/s (n=100000) 
+0

Pencerelerde mi çalışıyorsunuz? Aynı kodu linux veya mac üzerinde deneyebilir misiniz? Benim deneyimime göre, pencerelerdeki konsola yazmak ağrılı bir yavaş işlemdir, oysa Big Three'nin diğer 2'sinde çok hızlıdır. – rmeador

+0

@rmeador: Linux üzerinde çalışıyorum. Biraz sonra daha fazla test yapabileceğim. Bunun yeni hatlar için normal olup olmadığını veya kurulumun (OS, terminal, Perl, donanım, vb) b/c olup olmadığını bilmiyordum. Yanıtların söylediği gibi, – vol7ron

+0

, yeni satır her zaman yavaş, sadece garip konsol desteği olan Windows nedeniyle tamamen beklenmedik bir yavaşlama görüyorsun merak ediyorum. – rmeador

cevap

12

Bu arabelleğin bununla ilgili çok şey olduğunu sanmıyorum. Sanırım bunun nedeni, terminalin bir satırsonu yazdırırken (veya bir satırı doldurmak için yeterli karakter yazdırırken) kaydırma yapması gerektiğidir. Bir dosyaya veya /dev/null'a yazarken bu işlevlerin karşılaştırılmasını yaparken, pek bir fark yoktur.

use Benchmark; 
timethis(1000000, 'main'); 
timethis(1000000, 'main2'); 
select STDERR; $| = 0; select STDOUT; # enable buffering on STDERR 
sub main { print STDERR "you are the bomb. \n" } 
sub main2 { print STDERR "you are the bomb. " } 

$ perl benchmark.pl 2> a_file 
timethis 1000000: 21 wallclock secs (4.67 usr + 13.38 sys = 18.05 CPU) @ 55410.87/s 
timethis 1000000: 21 wallclock secs (4.91 usr + 13.34 sys = 18.25 CPU) @ 54797.52/s 

$ perl benchmark.pl 2> /dev/null 
timethis 1000000: 26 wallclock secs (2.86 usr + 10.36 sys = 13.22 CPU) @ 75648.69/s 
timethis 1000000: 27 wallclock secs (2.86 usr + 10.30 sys = 13.16 CPU) @ 76010.95/s 

$ perl benchmark.pl 2> a_file  (without buffering) 
timethis 1000000: 29 wallclock secs (3.78 usr + 12.14 sys = 15.92 CPU) @ 62806.18/s 
timethis 1000000: 29 wallclock secs (3.27 usr + 12.51 sys = 15.78 CPU) @ 63367.34/s 

$ perl benchmark.pl 2> /dev/tty (window has 35 lines and buffers 10000, YMMV) 
[ 200000 declarations of how you are a bomb deleted ] 
timethis 100000: 53 wallclock secs (0.98 usr + 3.73 sys = 4.72 CPU) @ 21190.93/s 
timethis 100000: 9 wallclock secs (0.36 usr + 1.94 sys = 2.30 CPU) @ 43535.05/s 

Özet: ekstra yıkama, performansı yaklaşık% 10 azaltır. Terminalde ekstra kaydırma, performansı yaklaşık% 50 azaltır.

+0

Bu, konsola yazılan herhangi bir dilin benzer bir performans isabeti anlamına geleceği anlamına mı geliyor? – justkt

+0

Bence bu doğru cevap olabilir. Düzenlemenin ilk örneğe göre karşılaştırılmasıyla gösterildiği gibi (iki yeni hattan diğerine karşı), gerçek zaman olan wallclock saniye dışında, CPU saniyeleri aynıdır. Farkın sadece bir kaydırma işleminden kaynaklanabileceğini düşünüyorum, sadece kaydırma işleminin neden olabileceğini veya imlecin bir satırsonu yeniden konumlandırıldığını varsayabilirim. – vol7ron

+0

@justkt, bu kriter için büyük bir ek olurdu. Deneyebilir misin :) – vol7ron

3

Newline flushes output.

en stdio uygulamalarda

, tamponlama çıkış cihazı ... Seri cihazlar, terminaller, modemler, fareler ve joystick dahil , normal olarak hat-tamponlanır türüne göre değişir; stdio o yeni satır

+0

çıkış terminaline ve ya olarak görülür: "Eğer bomba Eğer bomba ... Eğer bomba 100000 timethis.. # Wallclock saniye ..." veya "Bomba sizsiniz. Bomba sizsiniz. ... Siz bombasınız. Zaman 100000: # wallclock sn" ... Tüm çıktılar referans verilerden önce gösteriliyor. Kızarma bunun üzerinde hala bir etkisi var mı? Örneğinizin dediği gibi, genellikle cgi betiklerinde, kızarma ile ilgili problemleri fark ettim. düzenleme: bu yorum biçimlendirmeyi sürdürmüyor, 1. örnek çıktıyla yeni satırı listeler, 2. bunları arka arkaya yazdırır. – vol7ron

+0

Ek için teşekkürler, ama aynı zamanda diyor ki: "Perl'in yazdırma fonksiyonu gerçekten tekil olmayan çıkışı desteklemez - her bir karakter için fiziksel bir yazı.Yani, her ayrı çıkış komutundan sonra bir fiziksel yazmanın yapıldığı komut ara belleğini destekler. " - Baskı'nın her çalışmasının, çıktı almak için doğru olmasını, tamponlamanın gerekli olmadığını beklerdim. – vol7ron

8

It gets sadece dışarı tüm çizgi gönderir değil \n haddi zatında bu soruna neden olduğunu. Bunun yerine, print numaralı çağrılara \n karakteriyle karşılaşılana veya arabellek doluncaya kadar OS tarafından tamponlanır. Bu noktada, çıktı tamponu ekrana akıtılır. Çıktının ekrana akıtılması (nispeten) pahalı bir işlemdir, bu yüzden çıkış arabelleğini birçok kez yıkamanız için döngü, arabelleği yalnızca bir kez yıkadığınız döngüden çok daha yavaş bir performansa sahiptir (bu durum, sizin program çıkışı).

+1

Ayrıca, otomatik temizleme özelliğini açmayı denedim: "$ | ++;" ikinci satırda. Bunun herhangi bir etkisi yok gibi görünüyor. – vol7ron

İlgili konular