给Perl的打印列表或串联字符串更快吗?

use*_*033 1 printing perl performance

选项A:

print $fh $hr->{'something'}, "|", $hr->{'somethingelse'}, "\n";
Run Code Online (Sandbox Code Playgroud)

选项B:

print $fh $hr->{'something'} . "|" . $hr->{'somethingelse'} . "\n";
Run Code Online (Sandbox Code Playgroud)

Ale*_*ein 13

除非您执行数百万条这样的陈述,否则性能差异无关紧要.我真的建议专注于它们确实存在的性能问题 - 找到它的唯一方法是分析你的应用程序.

过早的优化是乔尔和杰夫多年来一直播放并且抱怨的事情.尝试优化某些东西只是浪费时间,直到你知道它很慢.


Sch*_*ern 13

答案很简单,没关系.正如许多人所指出的那样,这不会是你程序的瓶颈.即时发生优化甚至不会对您的表现产生任何影响.你必须先说明,否则你只是在猜测并浪费你的时间.

如果我们要浪费时间,让我们至少做正确的事.下面是做一个现实基准的代码.它实际上执行打印并将基准信息发送到STDERR.你运行它perl benchmark.plx > /dev/null以防止输出充斥你的屏幕.

这里有500万次迭代写入STDOUT.通过使用两者timethese(),cmpthese()我们获得所有基准测试数据.

$ perl ~/tmp/bench.plx 5000000 > /dev/null
Benchmark: timing 5000000 iterations of concat, list...
    concat:  3 wallclock secs ( 3.84 usr +  0.12 sys =  3.96 CPU) @ 1262626.26/s (n=5000000)
      list:  4 wallclock secs ( 3.57 usr +  0.12 sys =  3.69 CPU) @ 1355013.55/s (n=5000000)
            Rate concat   list
concat 1262626/s     --    -7%
list   1355014/s     7%     --
Run Code Online (Sandbox Code Playgroud)

这里有500万写入临时文件

$ perl ~/tmp/bench.plx 5000000
Benchmark: timing 5000000 iterations of concat, list...
    concat:  6 wallclock secs ( 3.94 usr +  1.05 sys =  4.99 CPU) @ 1002004.01/s (n=5000000)
      list:  7 wallclock secs ( 3.64 usr +  1.06 sys =  4.70 CPU) @ 1063829.79/s (n=5000000)
            Rate concat   list
concat 1002004/s     --    -6%
list   1063830/s     6%     --
Run Code Online (Sandbox Code Playgroud)

请注意额外的wallclock和sys时间,强调您打印的内容打印的内容一样重要.

列表版本的速度提高了约5%(请注意,这与Pavel的逻辑相反,强调了尝试仅仅考虑这些内容的无用性).你说你做了成千上万的这些吗?让我们看看......我的笔记本电脑上有100毫秒的挂钟时间(有蹩脚的I/O),所以你在这里做的最好的事情就是剃掉大约7毫秒.恭喜.如果您花了一分钟时间考虑这个问题,那么在您弥补该时间之前,将需要您对该代码进行40k次迭代.更不用说机会成本,在那一刻你可以优化更重要的东西.

现在,有人会说"现在我们知道哪种方式更快,我们应该快速编写它,并在我们编写的每个程序中节省时间,使整个练习变得有价值!" 不会.它仍然会占到程序运行时间的一小部分,远低于测量单个语句的5%.其次,这样的逻辑会使您优先考虑微优化而不是可维护性.

哦,和5.8.8中的不同,如5.10.0.

$ perl5.8.8 ~/tmp/bench.plx 5000000 > /dev/null
Benchmark: timing 5000000 iterations of concat, list...
    concat:  3 wallclock secs ( 3.69 usr +  0.04 sys =  3.73 CPU) @ 1340482.57/s (n=5000000)
      list:  5 wallclock secs ( 3.97 usr +  0.06 sys =  4.03 CPU) @ 1240694.79/s (n=5000000)
            Rate   list concat
list   1240695/s     --    -7%
concat 1340483/s     8%     --
Run Code Online (Sandbox Code Playgroud)

它甚至可能会改变,具体取决于您使用的Perl I/O层和操作系统.所以整个练习都是徒劳的.

微优化是一个傻瓜的游戏.始终首先进行配置并寻求优化算法. Devel :: NYTProf是一位优秀的探索者.

#!/usr/bin/perl -w

use strict;
use warnings;
use Benchmark qw(timethese cmpthese);

#open my $fh, ">", "/tmp/test.out" or die $!;
#open my $fh, ">", "/dev/null" or die $!;
my $fh = *STDOUT;
my $hash = {
    foo => "something and stuff",
    bar => "and some other stuff"
};

select *STDERR;
my $r = timethese(shift || -3, {
    list => sub {
        print $fh $hash->{foo}, "|", $hash->{bar};
    },
    concat => sub {
        print $fh $hash->{foo}. "|". $hash->{bar};
    },
});
cmpthese($r);
Run Code Online (Sandbox Code Playgroud)

  • 即使我运行您的基准测试,我的系统仍然会告诉您列表速度较慢.这也表明你不能选择以下变体之一:在某些系统上,前者更快,而在另一些系统上则更快. (2认同)