$ perl 1051579.pl s/iter loop3 loop1 loop2 loop3 17.5 -- -88% -92% loop1 2.08 740% -- -36% loop2 1.33 1210% 56% -- no memoize: 30.9833 wallclock secs (30.98 usr + 0.00 sys = 30.98 CPU) @ 1613.94/s (n=50000) with memoize: 0.816253 wallclock secs ( 0.82 usr + 0.00 sys = 0.82 CPU) @ 60975.61/s (n=50000) $ cat 1051579.pl #!/usr/bin/perl use strict; use warnings; use Benchmark qw(:all :hireswallclock); #use Memoize; my ($cnt1, $cnt2); sub loop1 { $cnt1=0; for my $j (0 .. 100) { for my $k (0 .. 100) { for my $l (0 .. 100) { $cnt1 += sin($j) + cos($k) + sqrt($l); } } } } sub loop2 { $cnt2=0; for my $j (0 .. 100) { my $sin_j = sin($j); for my $k (0 .. 100) { my $cos_k = cos($k); for my $l (0 .. 100) { $cnt2 += $sin_j + $cos_k + sqrt($l); } } } } open my $FH, '>', '/dev/null'; sub loop3 { $cnt1=0; for my $j (0 .. 100) { for my $k (0 .. 100) { for my $l (0 .. 100) { $cnt1 += sin($j) + cos($k) + sqrt($l); printf $FH "% 3u % 3u % 3u : %f\n", $j, $k, $l, $cnt1; } } } } cmpthese 5, { loop1 => q[ loop1( ) ], loop2 => q[ loop2( ) ], loop3 => q[ loop3( ) ], }; # double-check that the routines do the same thing! print "**** $cnt1 != $cnt2 ****\n" if abs($cnt1-$cnt2)>.0001; print "\n\n"; no warnings 'recursion'; # hideously expensive subroutine sub glarf { my $t = shift; return 1 if $t <2; return 2 if $t <3; return glarf($t-1)+glarf($t-2)+glarf($t-3); } my $iter=50000; my $fibsub = sub { glarf(10); #glarf(20); #glarf(30); glarf(40); glarf(50); glarf(100); }; timethis($iter, $fibsub, 'no memoize' ); # These two lines of code make it *much* faster use Memoize; memoize('glarf'); timethis($iter, $fibsub, 'with memoize' );