选项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/