performance - 给 Perl 的 print 一个列表或一个连接的字符串是否更快?

选项A:

print $fh $hr->{'something'}, "|", $hr->{'somethingelse'}, "\n";

选项B:

print $fh $hr->{'something'} . "|" . $hr->{'somethingelse'} . "\n";

最佳答案

答案很简单,没关系。正如许多人指出的那样,这不会成为您程序的瓶颈。将此优化为立即发生不太可能对您的性能产​​生任何影响。您必须先分析,否则您只是在猜测和浪费时间。

如果我们要在这上面浪费时间,至少让我们把它做好。下面是做一个现实基准测试的代码。它实际上打印并将基准测试信息发送到 STDERR。您将其作为 perl benchmark.plx >/dev/null 运行以防止输出淹没您的屏幕。

这是写入 STDOUT 的 500 万次迭代。通过同时使用 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%     --

这里有 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%     --

请注意额外的挂钟和系统时间,这表明您打印的内容与您正在打印的内容一样重要。

列表版本快了大约 5%(请注意,这与 Pavel 的逻辑相反,Pavel 强调尝试只考虑这些东西是徒劳的)。你说你要做几万个这样的?让我们看看... 100k 在我的笔记本电脑(有糟糕的 I/O)上需要 146 毫秒的挂钟时间,所以你在这里能做的最好的事情就是减少大约 7 毫秒。恭喜。如果您花一分钟时间考虑这个问题,您将需要对该代码进行 40k 次迭代才能弥补这段时间。更不用说机会成本了,在那一刻你本可以优化更重要的事情。

现在,有人会说“既然我们知道哪种方式更快,我们就应该以更快的方式编写它,并在我们编写的每个程序中节省时间,使整个练习变得有值(value)!”不会。它仍然占程序运行时间的一小部分,远低于测量单个语句的 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%     --

它甚至可能根据您使用的 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);

https://stackoverflow.com/questions/1440499/

相关文章:

user-interface - 用于编写 GUI 应用程序的编程语言

memory - 使用 16 位整数的重要性

c# - 在 C# 中比较两个数组

php - Laravel 检查数组是否为空

git - 致命的 : failed to read object Inter

c# - 确认信息

arrays - 确定一个值是否在排序数组中的 O 时间是多少?

python - 有效地比较python中的两组

ruby-on-rails - 手动安装 Xcode 命令行工具不起作用

flutter - 收到此错误 : java.net.BindException:地址已在使用中:无