Почему это занимает много времени для печати “\\n” в Perl?

Почему это занимает много времени для печати новой строки? Это - просто моя машина, или другие видят тот же эффект?

С новой строкой:

#!/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/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)

Править: Я хотел бы добавить, что размещение двух "\n" заставляет выполнение брать вдвое более долго, по крайней мере, в течение wallclock секунд.

timethis 100000: 16 wallclock secs ( 0.15 usr +  0.52 sys =  0.67 CPU) @ 149253.73/s (n=100000)
9
задан vol7ron 23 June 2010 в 19:03
поделиться

3 ответа

Я не думаю, что буферизация имеет к этому большое отношение. Я предполагаю, что это происходит потому, что терминал должен прокручиваться, когда вы печатаете новую строку (или печатаете достаточно символов, чтобы заполнить строку). Когда я сравниваю эти функции при записи в файл или на /dev/null, разница невелика.

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

Резюме: дополнительная промывка снижает производительность примерно на 10%. Дополнительная прокрутка на терминале снижает производительность примерно на 50%.

12
ответ дан 4 December 2019 в 09:12
поделиться

Не \n как таковое вызывает эту проблему. Скорее, последовательные вызовы print буферизируются ОС до тех пор, пока не встретится символ \n или буфер не будет заполнен. В этот момент буфер вывода выводится на экран. Смывание вывода на экран является (относительно) дорогой операцией, поэтому цикл, в котором вы многократно смываете буфер вывода, имеет гораздо более низкую производительность, чем цикл, в котором вы смываете буфер только один раз в конце (что происходит неявно при выходе из программы).

8
ответ дан 4 December 2019 в 09:12
поделиться

Newline flushes output.

В большинстве реализаций stdio буферизация зависит от типа устройства вывода ... Последовательные устройства, включая терминалы, модемы, мыши и джойстики, обычно буферизованы; stdio посылает всю строку только после получения новой строки

3
ответ дан 4 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: