思南建議使用方法調用語義來避開strict 'refs'
限制是最簡潔,最容易閱讀的解決方案。
我唯一擔心的是使用這種方法的速度懲罰可能是一個問題。我們都聽說過方法調用性能懲罰和可嵌入函數的速度優勢。
所以我決定運行一個基準(代碼和結果如下)。
結果表明,正常,內聯常量運行約快兩倍,法文字子程序名字叫,幾乎三次一樣快,方法與變量的子程序調用的名稱。最慢的方法是標準deref並調用no strict "refs";
。
但是,即使是最慢的方法是在我的系統上第二個超過140萬次相當不錯的快。
這些基準泯有關使用方法調用的方法來解決這個問題,我的一個保留。
use strict;
use warnings;
use Benchmark qw(cmpthese);
my $class = 'MyConstant';
my $name = 'VALUE';
my $full_name = $class.'::'.$name;
cmpthese(10_000_000, {
'Normal' => \&normal_constant,
'Deref' => \&direct_deref,
'Deref_Amp' => \&direct_deref_with_amp,
'Lit_P_Lit_N' => \&method_lit_pkg_lit_name,
'Lit_P_Var_N' => \&method_lit_pkg_var_name,
'Var_P_Lit_N' => \&method_var_pkg_lit_name,
'Var_P_Var_N' => \&method_var_pkg_var_name,
});
sub method_lit_pkg_lit_name {
return 7 + MyConstant->VALUE;
}
sub method_lit_pkg_var_name {
return 7 + MyConstant->$name;
}
sub method_var_pkg_lit_name {
return 7 + $class->VALUE;
}
sub method_var_pkg_var_name {
return 7 + $class->$name;
}
sub direct_deref {
no strict 'refs';
return 7 + $full_name->();
}
sub direct_deref_with_amp {
no strict 'refs';
return 7 + &$full_name;
}
sub normal_constant {
return 7 + MyConstant::VALUE();
}
BEGIN {
package MyConstant;
use constant VALUE => 32;
}
而且結果:在Windows XP中,情況因人而異與826的activeperl產生
Rate Deref_Amp Deref Var_P_Var_N Lit_P_Var_N Lit_P_Lit_N Var_P_Lit_N Normal
Deref_Amp 1431639/s -- -0% -9% -10% -29% -35% -67%
Deref 1438435/s 0% -- -9% -10% -28% -35% -67%
Var_P_Var_N 1572574/s 10% 9% -- -1% -22% -29% -64%
Lit_P_Var_N 1592103/s 11% 11% 1% -- -21% -28% -63%
Lit_P_Lit_N 2006421/s 40% 39% 28% 26% -- -9% -54%
Var_P_Lit_N 2214349/s 55% 54% 41% 39% 10% -- -49%
Normal 4353505/s 204% 203% 177% 173% 117% 97% --
結果。
如果你有機會改變這一模塊,http://search.cpan.org/perldoc?Readonly或http://search.cpan.org/perldoc?Attribute::Constant似乎爲此使用更適合。 – ephemient 2010-02-02 22:01:02
軟件工程團隊正在控制模塊(對我來說更精確,是自動生成的包含常量列表的數據庫後端)。他們沒有帶寬容量來打擾這種微小/瑣碎的事情,並且不會讓團隊以外的人混淆他們的代碼,而沒有主要業務需要證明變更風險的合理性。他們是在大型金融機構工作時的休息時間。 – DVK 2010-02-03 18:29:29