Rate OO_7 OO_8 OO_10 OO_9 OO_6 OO_5 OO_4 OO_3 OO_2 OO_1 sub2 sub1 inline
OO_7 70.4/s -- -0% -43% -44% -69% -70% -81% -88% -89% -91% -92% -95% -99%
OO_8 70.5/s 0% -- -43% -44% -69% -70% -81% -88% -89% -91% -92% -95% -99%
OO_10 124/s 76% 76% -- -1% -45% -46% -66% -79% -81% -84% -85% -91% -98%
OO_9 126/s 79% 79% 1% -- -44% -46% -66% -79% -81% -84% -85% -91% -98%
OO_6 227/s 222% 222% 83% 80% -- -2% -38% -62% -65% -71% -73% -84% -96%
OO_5 232/s 229% 229% 87% 84% 2% -- -37% -61% -65% -70% -73% -83% -96%
OO_4 367/s 421% 420% 195% 191% 62% 58% -- -39% -44% -53% -57% -74% -93%
OO_3 600/s 752% 752% 383% 376% 165% 159% 64% -- -9% -23% -29% -57% -88%
OO_2 656/s 832% 831% 428% 421% 189% 183% 79% 9% -- -16% -23% -53% -87%
OO_1 782/s1010% 1009% 529% 520% 244% 237% 113% 30% 19% -- -8% -44% -85%
sub2 847/s1103% 1102% 582% 572% 273% 266% 131% 41% 29% 8% -- -39% -84%
sub1 1388/s1871% 1869%1017%1001% 512% 499% 278% 131% 112% 78% 64% -- -73%
inline5179/s7252% 7246%4067%4009%2182%2134%1312% 763% 689% 562% 511% 273% --
####
#! perl -slw
use strict;
package OO_1;
## Blessed scalar;
## No named parameters;
## Direct attribute access (no get/set)
sub new { return bless \$_[1], $_[0]; }
sub plus1 { ++${ $_[ 0 ] } }
package OO_2;
## Blessed scalar;
## Named parameters;
## Direct attribute access (no get/set)
sub new {
my( $class, $value ) = @_;
return bless \$value, $class;
}
sub plus1 {
my( $self ) = shift;
++$$self;
}
package OO_3;
## Blessed hash;
## Named parameters;
## Direct attribute access (no get/set)
sub new {
my( $class, $value ) = @_;
my $self = { value => $value };
return bless $self, $class;
}
sub plus1 {
my( $self ) = shift;
++$self->{ value };
}
package OO_4;
## Blessed hash;
## Named parameters;
## lvalue get/setter
sub new {
my( $class, $value ) = @_;
my $self = { value => $value };
return bless $self, $class;
}
sub value : lvalue{ my $self = shift; $self->{ value } }
sub plus1 {
my( $self ) = shift;
$self->value()++;
}
package OO_5;
## Blessed hash;
## Named parameters;
## Separate Get & Set
sub new {
my( $class, $value ) = @_;
my $self = { value => $value };
return bless $self, $class;
}
sub getValue { my $self = shift; $self->{ value } }
sub setValue { my( $self, $newValue ) = @_; $self->{ value } = $newValue }
sub plus1 {
my( $self ) = shift;
$self->setValue( $self->getValue() + 1 );
}
package OO_6;
## Inherited blessed hash;
## Named parameters;
## Separate Get & Set; No overides
use base 'OO_5';
package OO_7;
## Inside-Out hash;
## Named parameters;
## Separate Get & Set
my %values;
sub new {
my( $class, $value ) = @_;
my $self = bless \$value;
$values{ $self } = $value;
return $self;
}
sub getValue{ my $self = shift; $values{ $self } }
sub setValue{ my( $self, $newValue ) = @_; $values{ $self } = $newValue; }
sub plus1{ my $self = shift; $self->setValue( $self->getValue() + 1 ); }
package OO_8;
## Inside-Out hash;
## Named parameters;
## Separate Get & Set; No overides.
use base 'OO_7';
package OO_9;
use Class::Std;
## Class::Std Inside Out hash;
## Named parameters;
## Separate Get & Set
my %i :ATTR( :name );
sub plus1 {
my $self = shift;
$self->set_i( $self->get_i() + 1 );
}
package OO_10;
## Inherited Class::Std Inside Out hash;
## Named parameters;
## Separate Get & Set; No overides;
use base 'OO_9';
package main;
use Benchmark qw[ cmpthese ];
our $MAX ||= 1e3;
print "MAX: $MAX";
sub plus1{ $_[ 0 ]++ }
sub plus1a{ my( $i ) = @_; ++$i }
cmpthese 1, {
inline => q[ my $i= 0; ++$i while $i < $MAX;
print'inline:',$i;],
sub1=> q[ my $i= 0; plus1( $i ) while $i < $MAX;
print'sub1: ', $i;],
sub2=> q[ my $i= 0; $i= plus1a($i ) while $i < $MAX;
print'sub2: ', $i;],
OO_1=> q[my $o= OO_1->new(0); my $i= 0; $i= $o->plus1() while $i < $MAX;
print'OO_1:', $i;],
OO_2=> q[my $o= OO_2->new(0); my $i= 0; $i= $o->plus1() while $i < $MAX;
print'OO_2: ', $i;],
OO_3=> q[my $o= OO_3->new(0); my $i= 0; $i= $o->plus1() while $i < $MAX;
print'OO_3: ', $i;],
OO_4=> q[my $o= OO_4->new(0); my $i= 0; $i= $o->plus1() while $i < $MAX;
print'OO_4: ', $i;],
OO_5=> q[my $o= OO_5->new(0); my $i= 0; $i= $o->plus1() while $i < $MAX;
print'OO_5: ', $i;],
OO_6=> q[my $o= OO_6->new(0); my $i= 0; $i= $o->plus1() while $i < $MAX;
print'OO_6: ', $i;],
OO_7=> q[my $o= OO_7->new(0); my $i= 0; $i= $o->plus1() while $i < $MAX;
print'OO_7: ', $i;],
OO_8=> q[my $o= OO_8->new(0); my $i= 0; $i= $o->plus1() while $i < $MAX;
print'OO_8: ', $i;],
OO_9=> q[my $o= OO_9->new({ i => 0 });
my $i= 0; $i= $o->plus1() while $i < $MAX;
print 'OO_9: ', $i;
],
OO_10=>q[my $o= OO_10->new({ i => 0 });
my $i= 0; $i= $o->plus1() while $i < $MAX;
print 'OO_10:', $i;
],
};
cmpthese -1, {
inline=>q[ my $i=0; ++$i while $i < $MAX; ],
sub1=>q[ my $i=0; plus1( $i ) while $i < $MAX; ],
sub2=>q[ my $i=0; $i= plus1a($i ) while $i < $MAX; ],
OO_1=>q[ my $o= OO_1->new(0); my $i=0; $i= $o->plus1() while $i < $MAX; ],
OO_2=>q[ my $o= OO_2->new(0); my $i=0; $i= $o->plus1() while $i < $MAX; ],
OO_3=>q[ my $o= OO_3->new(0); my $i=0; $i= $o->plus1() while $i < $MAX; ],
OO_4=>q[ my $o= OO_4->new(0); my $i=0; $i= $o->plus1() while $i < $MAX; ],
OO_5=>q[ my $o= OO_5->new(0); my $i=0; $i= $o->plus1() while $i < $MAX; ],
OO_6=>q[ my $o= OO_6->new(0); my $i=0; $i= $o->plus1() while $i < $MAX; ],
OO_7=>q[ my $o= OO_7->new(0); my $i=0; $i= $o->plus1() while $i < $MAX; ],
OO_8=>q[ my $o= OO_8->new(0); my $i=0; $i= $o->plus1() while $i < $MAX; ],
OO_9=>q[ my $o= OO_9->new({ i => 0 });
my $i=0; $i= $o->plus1() while $i < $MAX;
],
OO_10=> q[ my $o = OO_10->new( {i => 0});
my $i=0; $i= $o->plus1() while $i < $MAX;
],
};
####
c:\test>b-recursive-nosub.pl
Ack(3,0): 5
Ack(3,0): 5
1 trial of Recursive Ack 3,0 (227us total)
1 trial of Iterative Ack 3,0 (111us total)
c:\test>b-recursive-nosub 8
Ack(3,8): 2045
Ack(3,8): 2045
1 trial of Recursive Ack 3,8 (13.698s total)
1 trial of Iterative Ack 3,8 (3.328s total)
c:\test>b-recursive-nosub 9
Ack(3,9): 4093
Ack(3,9): 4093
1 trial of Recursive Ack 3,9 (162.104s total)
1 trial of Iterative Ack 3,9 (13.234s total)
####
use strict;
use Benchmark::Timer; my $T = new Benchmark::Timer;
no warnings 'recursion';
my($Ack,$Fib,$Tak);
$Ack = sub
{
my ($x, $y) = @_;
return $y + 1 if $x == 0;
return $Ack->($x - 1, 1) if $y == 0;
$Ack->($x - 1, $Ack->($x, $y - 1));
};
sub Ack {
my( $x, $y ) = @_;
my @stack;
push @stack, $x;
do {
$x = pop @stack;
if( $x == 0 ) {
++$y;
}
elsif( $y == 0 ) {
push @stack, $x - 1;
$y = 1;
}
else {
push @stack, $x - 1, $x;
--$y;
}
} while @stack;
return $y;
}
my $n = ($ARGV[0] || 0) - 1;
$T->start( 'Recursive Ack 3,' . ( $n+1 ) );
printf "Ack(%d,%d): %d\n",
3, $n + 1, $Ack->(3, $n + 1);
$T->stop( 'Recursive Ack 3,' . ( $n+1 ) );
$T->start( 'Iterative Ack 3,' . ( $n+1 ) );
printf "Ack(%d,%d): %d\n",
3, $n + 1, Ack( 3, $n + 1 );
$T->stop( 'Iterative Ack 3,' . ( $n+1 ) );
$T->report;