Почему это занимает много времени для печати новой строки? Это - просто моя машина, или другие видят тот же эффект?
С новой строкой:
#!/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)
Я не думаю, что буферизация имеет к этому большое отношение. Я предполагаю, что это происходит потому, что терминал должен прокручиваться, когда вы печатаете новую строку (или печатаете достаточно символов, чтобы заполнить строку). Когда я сравниваю эти функции при записи в файл или на /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%.
Не \n
как таковое вызывает эту проблему. Скорее, последовательные вызовы print
буферизируются ОС до тех пор, пока не встретится символ \n
или буфер не будет заполнен. В этот момент буфер вывода выводится на экран. Смывание вывода на экран является (относительно) дорогой операцией, поэтому цикл, в котором вы многократно смываете буфер вывода, имеет гораздо более низкую производительность, чем цикл, в котором вы смываете буфер только один раз в конце (что происходит неявно при выходе из программы).
Newline flushes output.
В большинстве реализаций stdio буферизация зависит от типа устройства вывода ... Последовательные устройства, включая терминалы, модемы, мыши и джойстики, обычно буферизованы; stdio посылает всю строку только после получения новой строки