最初,我一直在寻找一种快速访问哈希引用元素的方法(如果没有值可用,则使用默认值)。
所以我尝试了以下内容:
use strict;
use warnings;
use DateTime;
my $hashref = { };
for (0..249) {
my $lIdx = $_ * 2;
$hashref->{"MYKEY$lIdx"} = "MYVAL$lIdx";
}
sub WithVariable{
my $result = $hashref->{"MYKEY$_[0]"};
return defined $result ? $result : "NONE";
}
sub WithoutVariable{
return defined $hashref->{"MYKEY$_[0]"} ? $hashref->{"MYKEY$_[0]"} : "NONE";
}
$|++;
my @preciousvalues1 = ();
my @preciousvalues2 = ();
my $dt = DateTime->now;
for (1..25000) { for (0..498) { push @preciousvalues1, WithVariable($_) } }
my $lag = DateTime->now - $dt;
print "With a variable: ", $lag->seconds, "\n";
$dt = DateTime->now;
for (1..25000) { for (0..498) { push @preciousvalues2, WithoutVariable($_) } }
$lag = DateTime->now - $dt;
print "Without a variable: ", $lag->seconds, "\n";
print "Done\n";
但结果似乎是随机的,perl似乎在打印“Done”之后做了很多事情,并且需要永远退出。
我的问题是:
Perl版本:这是为MSWin32-x86-multi-thread构建的perl,v5.10.1
答案 0 :(得分:5)
//
(已定义或)运算符来测试已定义的值,并在一个步骤中指定默认值。$result = $hashref->{$key} // "NONE"如果定义了该值,则
将$result
设置为$hashref->{$key}
,否则设置为"NONE"
。
2.或多或少。如果它困扰你,打一个
use POSIX; POSIX::_exit(0);
在脚本的末尾。这将立即终止您的脚本,绕过Perl的正常关闭例程(以及您放入END { }
块的任何代码)。在此脚本上使用它可能不是什么大问题,但使用_exit
通常不是最佳做法。
答案 1 :(得分:2)
正如我在评论中所说,使用Benchmark进行这些比较。 Benchmark处理测试计时和打印报告的所有细节。
值得一提的另一件事是你的测试没有测试你的想法。您的测试会将值推送到@preciousvalues1
和@preciousvalues2
。每次测试迭代都会向其中一个阵列添加大约500个结果。由于您没有在迭代之间清除数组,因此您最终得到两个数组,每个数组包含 1250万条目。我想这会让你开始交换,并导致你进行缓慢的,半随机的执行时间。这也是退出程序延迟的原因。你已经为这些结构分配了大量的RAM。 Perl希望正确地拆除它们,并确保触发任何析构函数或END块。
这是一个清理版本的测试,专注于哈希访问。我添加了mobrule的解决方案进行比较。
use strict;
use warnings;
use Benchmark qw(cmpthese);
my $hashref = { };
for (0..249) {
my $lIdx = $_ * 2;
$hashref->{"MYKEY$lIdx"} = "MYVAL$lIdx";
}
sub WithVariable{
my $result = $hashref->{"MYKEY$_[0]"};
return defined $result ? $result : "NONE";
}
sub WithoutVariable{
return defined $hashref->{"MYKEY$_[0]"} ? $hashref->{"MYKEY$_[0]"} : "NONE";
}
cmpthese( 25000, {
"With Var" => sub {
my @vals;
push @vals, WithVariable($_) for 0..498;
},
"Without Var" => sub {
my @vals;
push @vals, WithoutVariable($_) for 0..498;
},
"Mobrule" => sub {
my @vals;
push @vals, $hashref->{"MYKEY$_"} // 'NONE' for 0..498;
}
} );
在我的系统上有以下结果:
Rate With Var Without Var Mobrule
With Var 1382/s -- -0% -49%
Without Var 1389/s 1% -- -49%
Mobrule 2700/s 95% 94% --
很明显,mobrule的解决方案更快,而且其他两个实现之间只有微小的差别。最大的区别是mobrule的解决方案不会执行其他两个实现使用的函数调用。