2017-02-23 24 views
3

Я занимался некоторыми исследованиями, и у меня сложилась такая ситуация. Если вы хотите записать на STDOUT (экран), вы не сможете выполнить многопоточный скрипт, который быстрее печатает данные, чем простой сценарий с одним потоком. Но, если вы пишете в файл, как это:Производительность с использованием STDOUT (экран) против обычного файла

myPrinter.perl > myPrint 

Изменение результата, и вы можете увидеть, что многопоточный подход получает лучшее время. Я сомневаюсь, поскольку STDOUT (экран) или выходной файл являются общими ресурсами, не будет ли время доступа аналогичным? Почему многопоточный подход только лучше работает с файлом?

Perl-скриптов, которые я использовал в экспериментах:

Single нить

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 STDOUT_» ... на самом деле выпускаете его на экране? Это займет больше времени, все рендеринг, перерисовка и многое другое. Время однопоточного, для экранирования и перенаправления. Я не знаю, как это влияет на несколько потоков, но я предполагаю, что это может быть только хуже. Кроме того, как говорит ThisSuitIsBlackNot, буферизация может отличаться. – zdim

ответ

2

Это можно объяснить, если запись в STDOUT требует внутренней блокировки.

Когда STDOUT подключен к терминалу, выход выдается после каждой новой строки. В противном случае STDOUT очищается только каждые 4 KiB или 8 KiB (в зависимости от вашей версии Perl).В последнем сценарии, по-видимому, требовалось меньше или меньше замков.

Вы можете использовать |cat вместо >file, чтобы получить такой же эффект.

Если ваш фактический работник тратит гораздо меньшую долю времени на запись в STDOUT, эта проблема должна исчезнуть.

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

yep, я тоже сделал этот тест. Я думаю, что ваш комментарий имеет смысл. Прочитав немного больше, я думаю, что узкое место находится в процессе рендеринга. –

Смежные вопросы