2017-02-23 43 views
3

我一直在做一些研究,我得到了這種情況。如果要寫入STDOUT(屏幕),則無法執行多線程腳本,該腳本可以更簡單地單一線程腳本來打印數據。但是,如果你寫一個這樣的文件:性能使用標準輸出(屏幕)vs普通文件

myPrinter.perl > myPrint 

結果的變化,你可以看到,多線程的方式得到更好的時間。我的疑問是,既然STDOUT(屏幕)或輸出文件都是共享資源,不會是訪問時間類似嗎? 爲什麼多線程方法只能執行更好的文件寫入?

,我在實驗中使用的Perl腳本是:

單線程

for my $i (1..100000000){ 
    print("things\n"); 
} 

多線程

use threads; 
use Thread::Queue 3.01 qw(); 

use constant NUM_WORKERS => 4; 


sub worker { 
    for my $i (1 .. 25000000){ 
     print("things\n"); 
    } 
} 

my $q = Thread::Queue->new(); #::any 

async { while (defined(my $job = $q->dequeue())) { worker($job); } } 
for 1..NUM_WORKERS; 

for my $i (1 .. 4){ 
    $q->enqueue($i); 
} 

$q->end(); 
$_->join for threads->list; 

現金:隊列執行拍攝從其中一個ikegami的答案。

+0

[患有緩衝嗎?](http://perl.plover.com/FAQs/Buffering.html) – ThisSuitIsBlackNot

+0

「_to the STDOUT_」是什麼意思......實際上讓它出現在屏幕上?這將需要更長的時間,所有的渲染,重繪和什麼。計時單線程,屏幕與重定向。我不知道它如何影響多線程,但我的猜測是它只會更糟。此外,正如ThisSuitIsBlackNot所說,緩衝可能會有所不同。 – zdim

回答

2

如果寫入STDOUT需要某種形式的內部鎖定,則可以解釋這一點。

當STDOUT連接到終端時,輸出在每個換行符後被刷新。否則,STDOUT只會每4 KiB或8 KiB刷新一次(取決於您的Perl版本)。後一種情況大概需要更少或更短的鎖。

您可以使用|cat而不是>file來獲得相同的效果。

如果您的實際工作人員將時間寫入標準輸出的時間比例要小得多,則此問題應該消失。

1

您輸出數據的速度有多快受到目標性能的限制。如果您寫入本地文件,性能受底層操作系統,文件系統和磁盤速度的限制。如果您寫入網絡文件系統上的文件,則會受到網絡速度和文件服務器性能等因素的限制。某些操作系統級別的緩衝有助於加快速度。

如果你寫入STDOUT,它取決於STDOUT的目標是什麼。 STDOUT可以被重定向到一個文件,傳送到另一個進程並打印到終端。在所有這些情況下,寫入速度再次取決於目標介質。與本地文件相比,終端寫入速度通常很慢。但是,這不是STDOUT與文件相關的問題,而是STDOUT結束的問題。

+0

是的,你說得對。我應該澄清,當我寫STDOUT時,我在屏幕上思考。我知道每個資源都有不同的限制,但是,我想知道與寫入屏幕到寫入文件有什麼不同。我認爲zdim在評論中得到了它。 –

+0

@IvánRodríguezTorres:這意味着你的問題與Perl和STDOUT完全無關,但你只需要問輸出到終端的速度取決於文件的輸出。 –

2

一個例子,跟隨我的評論。我從問題中瞭解到,您比較了終端上打印的STDOUT打印和那些重定向到文件的打印。

伏法在控制檯

time perl -we'print "hello\n" for 1..1_000_000' 

時間:  0.209u 1.562s 0:17.65 9.9% 0+0k 0+0io 0pf+0w  (tcsh中)

time perl -we'print "hello\n" for 1..1_000_000' > many_writes.out 

時間:  0.104u 0.005s 0:00.11 90.9% 0+0k 0+11720io 0pf+0w

也就是說17.65秒與0.11秒。打印到終端非常非常慢。

對於多線程,我預計這種差異會更加明顯。

+0

是的,我也做了這個測試。我認爲你的評論很重要。在閱讀更多內容後,我認爲瓶頸在渲染過程中。 –

相關問題