Во-первых, я не доверяю тестам, которые не вижу. Слишком легко понять их неправильно. Я тестировал их сам.
use strict;
use warnings;
use Benchmark qw( cmpthese );
sub new { return bless({}, $_[0]); }
sub myMethod { }
my %tests = (
rt => '$foo->$method() for 1..1000;',
ct => '$foo->myMethod() for 1..1000;',
);
$_ = 'use strict; use warnings; our $foo; our $method; ' . $_
for values(%tests);
our $foo = __PACKAGE__->new();
our $method = 'myMethod';
cmpthese(-3, \%tests);
Я могу повторить ваши результаты.
Rate rt ct
rt 1879/s -- -19%
ct 2333/s 24% --
(Rate is 1/1000th of actual rate.)
Это кажется довольно большим, но проценты могут вводить в заблуждение чем-то таким быстрым. Давайте посмотрим на разницу в абсолютных временах.
Compile-time: 2333000 calls per second = 429 nanoseconds per call
Run-time: 1879000 calls per second = 532 nanoseconds per call
Difference: 103 nanoseconds per call.
Не так много. Так где же это время проведено?
$ perl -MO=Concise,-exec -e'$foo->myMethod()' $ perl -MO=Concise,-exec -e'$foo->$method()'
1 <0> enter = 1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{ = 2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark s = 3 <0> pushmark s
4 <#> gvsv[*foo] s = 4 <#> gvsv[*foo] s
+ 5 <#> gvsv[*method] s
5 <$> method_named[PV "myMethod"] ! 6 <1> method K/1
6 <1> entersub[t2] vKS/TARG = 7 <1> entersub[t3] vKS/TARG
7 <@> leave[1 ref] vKP/REFC = 8 <@> leave[1 ref] vKP/REFC
-e syntax OK = -e syntax OK
Кажется, единственное отличие - это поиск в таблице дополнительных символов. 100 нс кажется чрезмерным для этого. Но чтобы быть уверенным, сравните с чем-то крошечным, скажем, как добавление одного.
$ perl -MO=Concise,-exec -e'my $y = $x;' $ perl -MO=Concise,-exec -e'my $y = $x + 1;'
1 <0> enter = 1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{ = 2 <;> nextstate(main 1 -e:1) v:{
3 <#> gvsv[*x] s = 3 <#> gvsv[*x] s
+ 4 <$> const[IV 1] s
+ 5 <2> add[t3] sK/2
4 <0> padsv[$y:1,2] sRM*/LVINTRO = 6 <0> padsv[$y:1,2] sRM*/LVINTRO
5 <2> sassign vKS/2 = 7 <2> sassign vKS/2
6 <@> leave[1 ref] vKP/REFC = 8 <@> leave[1 ref] vKP/REFC
-e syntax OK = -e syntax OK
Подставляя этот код и our $x = 100;
в код теста выше, мы получаем
Rate addition baseline
addition 4839/s -- -26%
baseline 6532/s 35% --
(Rate is 1/1000th of actual rate.)
Итак,
Basline: 6553000/s = 153 nanoseconds per assignment
Addition: 4839000/s = 207 nanoseconds per assignment+addition
Difference: 54 nanoseconds per addition
Так разумно ли, чтобы простой просмотр таблицы символов занимал вдвое больше времени, чем добавление одного? Возможно, так как это включает хеширование строки и поиск строки в коротком связанном списке.
Вы действительно хотите потратить лишние 100 нс здесь и там? Нет, наверное.