use warnings; use strict; use Benchmark; use Test::More tests => 4; my $_fact3; $_fact3 = sub { my ($result, $counter, $max) = @_; return $result if $counter > $max; @_ = (($result * $counter), ($counter + 1), $max); goto $_fact3; }; my $number = shift or die "No number supplied"; validate_factorial_routines($number); print "Timing factorial of $number\n"; timethese(100_000, { 'recursion 1' => sub { fact0($number) }, 'recursion 2' => sub { fact1($number) }, 'typeglob' => sub { fact2($number) }, 'lexical' => sub { fact3($number) }, }); sub validate_factorial_routines { my $num = shift; my @result = (fact0($num), fact1($num), fact2($num), fact3($num)); is(fact0(5), 120, 'fact0 should return the correct amount'); is(fact1(5), 120, 'fact1 should return the correct amount'); is(fact2(5), 120, 'fact2 should return the correct amount'); is(fact3(5), 120, 'fact3 should return the correct amount'); } sub fact0 { my ($num) = @_; return _fact0(1,1,$num); } sub _fact0 { my ($result, $counter, $max) = @_; return $result if $counter > $max; return _fact1(($result * $counter), ($counter + 1), $max); } sub fact1 { @_ = ( 1, 1, $_[0] ); return &_fact1; } sub _fact1 { my ($result, $counter, $max) = @_; return $result if $counter > $max; @_ = (($result * $counter), ($counter + 1), $max); return &_fact1; } sub fact2 { my ($num) = @_; @_ = (1, 1, $num); goto &_fact2; } sub _fact2 { my ($result, $counter, $max) = @_; return $result if $counter > $max; @_ = (($result * $counter), ($counter + 1), $max); goto &_fact2; } sub fact3 { my ($num) = @_; @_ = (1, 1, $num); goto $_fact3; } __output__ 1..4 ok 1 - fact0 should return the correct amount ok 2 - fact1 should return the correct amount ok 3 - fact2 should return the correct amount ok 4 - fact3 should return the correct amount Timing factorial of 5 Benchmark: timing 100000 iterations of lexical, recursion 1, recursion 2, typeglob... lexical: 17 wallclock secs (16.19 usr + 0.02 sys = 16.20 CPU) @ 6171.70/s (n=100000) recursion 1: 4 wallclock secs ( 3.74 usr + 0.00 sys = 3.74 CPU) @ 26773.76/s (n=100000) recursion 2: 14 wallclock secs (13.41 usr + 0.00 sys = 13.41 CPU) @ 7459.35/s (n=100000) typeglob: 17 wallclock secs (17.61 usr + 0.00 sys = 17.61 CPU) @ 5678.91/s (n=100000)