Perl 变量实例化与双哈希引用访问
起初,我在寻找一种访问hash ref元素的快速方法(如果没有可用的值,则使用默认值) 因此,我尝试了以下方法:Perl 变量实例化与双哈希引用访问,perl,Perl,起初,我在寻找一种访问hash ref元素的快速方法(如果没有可用的值,则使用默认值) 因此,我尝试了以下方法: use strict; use warnings; use DateTime; my $hashref = { }; for (0..249) { my $lIdx = $_ * 2; $hashref->{"MYKEY$lIdx"} = "MYVAL$lIdx"; } sub WithVariable{ my $result = $hashref->{
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似乎在打印“完成”之后做了很多事情,并且要花很长时间才能退出
我的问题是:
/
(已定义或)运算符测试已定义的粗糙度,并在一个步骤中指定默认值在脚本的末尾。这将立即结束脚本,绕过Perl的正常关闭例程(以及放入
end{}
块中的任何代码)。在这个脚本上使用它可能没什么大不了的,但是通常使用\u exit
不是一个最佳实践,正如我在评论中已经说过的,使用它来进行这些比较。Benchmark处理测试计时和打印报告的所有精细细节
另一件值得一提的事情是,你的测试并不是在测试你认为它是什么。您的测试将值推送到@preciousvalues1
和@preciousvalues2
上。每个测试迭代将大约500个结果添加到其中一个数组中。由于没有在迭代之间清除数组,因此最终会得到两个数组,每个数组都有大约1250万个条目。我猜这会驱使您交换,并导致您进入缓慢、半随机的执行时间。这也是退出程序延迟的原因。您已经为这些结构分配了大量RAM。Perl希望正确地分解它们,并确保触发任何析构函数或结束块
这是一个经过清理的测试版本,重点是哈希访问。我添加了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的解决方案没有执行其他两个实现所使用的函数调用。您确实应该使用基准模块进行此类比较。基准测试是核心的一部分,所以没有理由不使用它。您需要更改Mobrule版本以使用
$hashref->{“MYKEY$\}
来获得准确的基准。虽然我认为这不会改变结果。谢谢,文达苏。又一个例子说明了尝试测试一件事情是多么容易,最后又测试了另一件事情。我修复了代码并更新了结果。
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% --