Wow, I'm impressed.
An idealized benchmark shows only a 25% gain by memoizing, so I agree, it doesn't worth it.
Rate classic memoized
classic 75415/s -- -19%
memoized 93110/s 23% --
| [reply] [d/l] [select] |
An idealized benchmark
Hm. I'm not sure that "idealized" really described your benchmark. And neither does "memoized"--more like "hard-coded".
Are you really suggesting that every user of every class should build a lexical cache of every method for each class they use, in each package they use it, and then hard-code all their method calls in terms of that lexical cache?
I've removed your hard-coded version as unrealistic, and replaced with paranoid() reflecting the OPs suggested methodology. I've also added a realistically memoised version of that suggestion to show that it doesn't help:
use strict;
my $obj = Class->new;
sub classic {
$obj->meth0->meth1->meth2->meth3->meth4->meth5->meth6->meth7->meth8-
+>meth9;
}
sub paranoid {
$obj and ref $obj and my $ref0 = $obj->can('meth0');
$obj and ref $obj and my $ref1 = $obj->can('meth1');
$obj and ref $obj and my $ref2 = $obj->can('meth2');
$obj and ref $obj and my $ref3 = $obj->can('meth3');
$obj and ref $obj and my $ref4 = $obj->can('meth4');
$obj and ref $obj and my $ref5 = $obj->can('meth5');
$obj and ref $obj and my $ref6 = $obj->can('meth6');
$obj and ref $obj and my $ref7 = $obj->can('meth7');
$obj and ref $obj and my $ref8 = $obj->can('meth8');
$obj and ref $obj and my $ref9 = $obj->can('meth9');
$obj->$ref0->$ref1->$ref2->$ref3->$ref4->$ref5->$ref6->$ref7->$ref
+8->$ref9;
}
my %memo;
sub memoized {
$obj and ref $obj and my $ref0 = $memo{ meth0 } || $obj->can('meth
+0');
$obj and ref $obj and my $ref1 = $memo{ meth1 } || $obj->can('meth
+1');
$obj and ref $obj and my $ref2 = $memo{ meth2 } || $obj->can('meth
+2');
$obj and ref $obj and my $ref3 = $memo{ meth3 } || $obj->can('meth
+3');
$obj and ref $obj and my $ref4 = $memo{ meth4 } || $obj->can('meth
+4');
$obj and ref $obj and my $ref5 = $memo{ meth5 } || $obj->can('meth
+5');
$obj and ref $obj and my $ref6 = $memo{ meth6 } || $obj->can('meth
+6');
$obj and ref $obj and my $ref7 = $memo{ meth7 } || $obj->can('meth
+7');
$obj and ref $obj and my $ref8 = $memo{ meth8 } || $obj->can('meth
+8');
$obj and ref $obj and my $ref9 = $memo{ meth9 } || $obj->can('meth
+9');
$obj->$ref0->$ref1->$ref2->$ref3->$ref4->$ref5->$ref6->$ref7->$ref
+8->$ref9;
}
use Benchmark qw/cmpthese/;
cmpthese(1E6,
{
classic => \&classic,
paranoid => \¶noid,
memoized => \&memoized,
});
package Class;
sub new { bless {}, $_[0] }
sub meth0 { $_[0] }
sub meth1 { $_[0] }
sub meth2 { $_[0] }
sub meth3 { $_[0] }
sub meth4 { $_[0] }
sub meth5 { $_[0] }
sub meth6 { $_[0] }
sub meth7 { $_[0] }
sub meth8 { $_[0] }
sub meth9 { $_[0] }
__END__
C:\test>junk
Rate memoized paranoid classic
memoized 101102/s -- -9% -65%
paranoid 111099/s 10% -- -61%
classic 286123/s 183% 158% --
I was tempted to add a Moose example, but that would be just like bear-baiting.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
I was tempted to add a Moose example, but that would be just like bear-baiting.
A Moose example wouldn't be any different because you are not hitting upon the places where Moose is slow. A method call in Moose is the same as a method call in a vanilla Perl object, and Moose does not override &can, seems like you are just trolling Moose again. Oh well.
| [reply] [d/l] |
> An idealized benchmark
> >Hm. I'm not sure that "idealized" really described your benchmark. And neither does "memoized"--more like "hard-coded".
It's called a lower bound approximation.
And BTW I also idealized by avoiding any inheritance.
| [reply] |