Sinan's suggestion to use method invocation semantics to get around strict 'refs' is the purest, easiest to read solution.
My only concern about this was that speed limits for using this approach could be a problem. We all heard about penalties for method performance and the speed advantages of built-in functions.
So, I decided to run the test (code and results follow).
The results show that regular, built-in constants work about two times faster than method calls with the literal routine name, and almost three times faster than method calls with variable routine names. The slowest approach is standard separation and calling no strict "refs"; .
But even the slowest approach works pretty fast at more than 1.4 million times per second on my system.
These tests erase my one caveat about using a method invocation method to solve this problem.
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; }
And the results:
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% --
Results obtained using ActivePerl 826 in Windows XP, YMMV.
source share