我花了太长时间才使用警告; 严格 在Perl,但现在我做了,我看到了优点.
我还不确定的一件事是何时定义一个临时变量.这似乎是一件微不足道的事情,但我运行了很多蒙特卡罗模拟,其中失去一点时间加起来超过10000次迭代.我一直懒得在更快的模拟上使用严格/警告,但它们变得更加复杂,所以我真的需要.
所以(切掉代码来计算东西)我想知道是否
sub doStuff
{
my $temp;
for my $x (1..50)
{
$temp = $x**2;
}
for my $x (1..50)
{
$temp = $x**3;
}
}
Run Code Online (Sandbox Code Playgroud)
要么
sub doStuff
{
for my $x (1..50)
{
my $temp = $x**2;
}
for my $x (1..50)
{
my $temp = $x**3;
}
}
Run Code Online (Sandbox Code Playgroud)
效率更低/更高,或者如果违反了一些我还不知道的Perl编码.
这两者之间的效率足够接近,任何实际处理都相形见绌.所以我会通过代码 - 如果$tmp
确实是临时的并且在循环之后不需要,那么由于所有其他原因,最好将其保持在内部(作用域).
由于这是关于优化我想离题.这些微问题可能会产生影响.但是,您真正获得的地方首先是算法级别,然后适当选择数据结构和技术.低级调整是最后要考虑的事情,并且通常有语言功能和库使它们无关紧要.也就是说,人们应该知道一个人的工具而不是浪费时间.
此外,通常在代码清晰度和效率之间进行权衡.如果是这样,我建议编码的正确性和清晰度.然后,如果需要,谨慎和逐步地进行分析和优化,并在两者之间进行大量测试.
这是一个比较,作为核心模块Benchmark的基本使用示例.我抛出一个额外的操作,并添加其他没有临时的情况.
use warnings 'all';
use strict;
use Benchmark qw(cmpthese);
my $x;
sub tmp_in {
for (1..10_000) {
my $tmp = 2 * $_;
$x = $tmp + $_;
}
return $x;
}
sub tmp_out {
my $tmp;
for (1..10_000) {
$tmp = 2 * $_;
$x = $tmp + $_;
}
return $x;
}
sub no_tmp {
for (1..10_000) { $x = 2 * $_ + $_ }
return $x;
}
sub base {
for (1..10_000) { $x += $_ }
return $x;
}
sub calc {
for (1..10_000) { $x += sin sqrt(rand()) }
return $x;
}
cmpthese(-10, {
tmp_in => sub { tmp_in },
tmp_out => sub { tmp_out },
no_tmp => sub { no_tmp },
base => sub { base },
calc => sub { calc },
});
Run Code Online (Sandbox Code Playgroud)
输出(在v5.16上)
Rate calc tmp_in tmp_out no_tmp base calc 623/s -- -11% -26% -44% -59% tmp_in 698/s 12% -- -17% -37% -54% tmp_out 838/s 34% 20% -- -25% -44% no_tmp 1117/s 79% 60% 33% -- -26% base 1510/s 142% 116% 80% 35% --
所以它们不同,显然是循环中的声明成本.但是tmp
版本在列表中.而且,这通常只是开销,所以它被夸大了.还有其他方面 - no_tmp
例如,在一个语句中运行.只有当您的处理主要是迭代时,这些事情才有意义.仅生成(高质量)伪随机数是昂贵的.
这也可能在不同的硬件和软件版本上(疯狂地)不同.我在更好的机器上使用v5.10的结果有点不同.将样本"计算"替换为您的处理,并在实际硬件上运行,以获取是否重要的相关度量.
归档时间: |
|
查看次数: |
273 次 |
最近记录: |