为什么要花这么长时间才能打印\";用Perl?
为什么打印新行要花这么长时间?这只是我的机器,还是其他人也看到了同样的效果 新行:为什么要花这么长时间才能打印\";用Perl?,perl,benchmarking,Perl,Benchmarking,为什么打印新行要花这么长时间?这只是我的机器,还是其他人也看到了同样的效果 新行: #!/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
#!/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)
#!/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)
没有新线:
#!/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)
#!/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)
Edit:我想补充一点,放置两个“\n”会导致执行失败
两倍的时间,至少是挂钟秒
timethis 100000: 16 wallclock secs ( 0.15 usr + 0.52 sys = 0.67 CPU) @ 149253.73/s (n=100000)
新线
在大多数stdio实现中,缓冲随输出设备的类型而变化。。。串行设备,包括终端、调制解调器、鼠标和操纵杆,通常是线路缓冲的stdio仅在获得换行符时才发送整行内容
导致此问题的不是
\n
本身。相反,操作系统会缓冲对print
的连续调用,直到遇到\n
字符或缓冲区已满。此时,输出缓冲区被刷新到屏幕上。将输出刷新到屏幕是一个(相对)昂贵的操作,因此多次刷新输出缓冲区的循环比只在最后刷新一次缓冲区的循环(在程序退出时隐式发生)的性能要慢得多。我认为缓冲与此没有多大关系。我猜这是因为终端在打印换行符时需要滚动(或者打印足够的字符来填充一行)。当我将这些函数写入一个文件或/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%的性能。输出到终端,并被视为:“你是炸弹。你是炸弹……你是炸弹。计时这100000:#墙钟秒…”或“你是炸弹。你是炸弹……你是炸弹。计时这100000:#墙钟秒…”因此,所有输出都显示在基准数据之前。冲洗对这一点仍然有影响吗?我只注意到刷新的问题,就像你的例子所说的,通常在cgi脚本中。编辑:此注释不保留格式,第一个示例列出了带换行符的输出,第二个示例连续打印。感谢您的添加,但它还表示:“Perl的打印函数不支持真正的无缓冲输出—每个字符的物理写入。相反,它支持命令缓冲,即在每个单独的输出命令之后进行一次物理写入。”——我希望每次打印都能直接输出,不需要缓冲。我还尝试了启用自动刷新:“$|++”;“在第二行。这似乎没有任何效果。那么这是否意味着任何语言写入控制台都会产生类似的性能影响?我认为这可能是正确的答案。如将我的编辑与第一个示例(两行换行与一行换行)进行比较所示。”,除了wallclock秒(即实际时间)外,CPU秒数大致相同。我认为这种差异只能归结为一个终端操作,我只能假设这是由滚动或从换行符重新定位光标引起的。@justkt,这对基准测试来说是一个很好的补充。你能试试吗?:)它does与缓冲有关。终端是线路缓冲的(在每个终端上刷新\n);重定向到文件或/dev/null会关闭此功能。您是在windows上运行的吗?您能在linux或mac上尝试相同的代码吗?根据我的经验,在windows上向控制台写入代码是一个非常缓慢的过程,而在三大主机中的其他两个主机上则非常非常快。@rmeador:我是在linux上运行的。我可以做一些进一步的测试我不知道这对于新行来说是常见的,还是b/c设置(操作系统、终端、Perl、硬件等).正如答案所说,新线总是很慢,我只是想知道你是否看到了完全出乎意料的减速,因为Windows有奇怪的控制台支持。@rmeador:gotcha-不,不使用Windows。正如mobrule所说,新线并不总是很慢,问题是终端,是否像其他人所说的那样与缓冲区相关,或者不是。我想这需要对航站楼发生的事情有更多的了解。当我看到连续的“你就是炸弹”时,我很难看出这是一个冲洗问题。“当遇到问题时,会将其打印到屏幕上-在打印之前不会有任何延迟。-1因为你没有用你的评论更新你的问题。