use Benchmark qw(:all);
use Math::BigInt;
sub recurse {
#divide and conquer
unshift @_, 1 if 2 != @_;
my ($m, $n) = @_;
if ($m < $n) {
my $k = int($m/2 + $n/2);
return recurse($m, $k) * recurse($k+1, $n);
}
else {
return new Math::BigInt->new($m);
}
}
sub iterate {
my $result = Math::BigInt->new(1);
$result *= $_ for 2..shift;
return $result
}
sub direct {
my $result = Math::BigInt->new(shift);
return $result->bfac();
}
cmpthese(1000, {
'recurse' => sub { recurse( 100) },
'iterate' => sub { iterate( 100) },
'direct' => sub { direct( 100) },
});
####
Benchmark: timing 1000 iterations of direct, iterate, recurse...
direct: 1 wallclock secs ( 1.68 usr + 0.00 sys = 1.68 CPU) @ 595.24/s (n=1000)
iterate: 10 wallclock secs ( 9.57 usr + 0.00 sys = 9.57 CPU) @ 104.49/s (n=1000)
recurse: 9 wallclock secs ( 9.54 usr + 0.00 sys = 9.54 CPU) @ 104.82/s (n=1000)
Rate iterate recurse direct
iterate 104/s -- -0% -82%
recurse 105/s 0% -- -82%
direct 595/s 470% 468% --
####
use Benchmark qw(:all);
use Math::GMP;
sub recurse {
#divide and conquer
unshift @_, 1 if 2 != @_;
my ($m, $n) = @_;
if ($m < $n) {
my $k = int($m/2 + $n/2);
return recurse($m, $k) * recurse($k+1, $n);
}
else {
return new Math::GMP $m;
}
}
sub iterate {
my $result = new Math::GMP 1;
$result *= $_ for 2..shift;
return $result
}
sub direct {
my $result = new Math::GMP shift;
return $result->bfac();
}
cmpthese(10, {
'recurse' => sub { recurse( 25_000) },
'iterate' => sub { iterate( 25_000) },
'direct' => sub { direct( 25_000) },
});
####
Benchmark: timing 10 iterations of direct, iterate, recurse...
direct: 0 wallclock secs ( 0.24 usr + 0.01 sys = 0.25 CPU) @ 40.00/s (n=10)
(warning: too few iterations for a reliable count)
iterate: 8 wallclock secs ( 7.81 usr + 0.00 sys = 7.81 CPU) @ 1.28/s (n=10)
recurse: 8 wallclock secs ( 7.73 usr + 0.00 sys = 7.73 CPU) @ 1.29/s (n=10)
Rate iterate recurse direct
iterate 1.28/s -- -1% -97%
recurse 1.29/s 1% -- -97%
direct 40.0/s 3024% 2992% --