为什么在Perl中打印“\ n”需要这么长时间?

时间:2010-06-23 18:40:36

标签: 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 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)
  

编辑:我想补充说,放置两个“\ n”会导致执行执行   两倍的时间,至少是挂钟秒。

timethis 100000: 16 wallclock secs ( 0.15 usr +  0.52 sys =  0.67 CPU) @ 149253.73/s (n=100000)

3 个答案:

答案 0 :(得分:12)

我不认为缓冲与它有很大关系。我猜这是因为终端需要在打印换行符时滚动(或打印足够的字符来填充一行)。当我对写入文件或/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%。

答案 1 :(得分:8)

导致此问题的不是\n本身。相反,操作系统会缓冲对print的连续调用,直到遇到\n字符或缓冲区已满。此时,输出缓冲区将刷新到屏幕。将输出刷新到屏幕是一个(相对)昂贵的操作,因此,多次刷新输出缓冲区的循环比在最后只刷新缓冲区一次的循环要慢得多(这种情况在你的程序退出)。

答案 2 :(得分:3)

换行符flushes output

  

在大多数stdio实现中,缓冲因输出设备的类型而异...串行设备,包括终端,调制解调器,鼠标和操纵杆通常是行缓冲的; stdio仅在获取换行符时才发送整行