#!perl use strict; use warnings; use Benchmark 'cmpthese'; use vars qw/@subs $time/; $time=-10; my @lines=split /\n/,<<'EOF_RULES'; # No-op $a+= $k[0]; $a+= $k[1] <<8; $a+= $k[2] <<16; $a+= $k[3] <<24; $b+= $k[4]; $b+= $k[5] <<8; $b+= $k[6] <<16; $b+= $k[7] <<24; $c+= $k[8] <<8; $c+= $k[9] <<16; $c+= $k[10] <<24; EOF_RULES my $template=<<'EOF_TEMPLATE'; sub { my @k=@_; my ($a, $b, $c) = (0,0,0); #-TEMPLATE-# return $a+$b+$c; } EOF_TEMPLATE for my $num (0..$#lines) { (my $t=$template)=~s[#-TEMPLATE-#] {"#Len:$num\n".join "\n",@lines[0..$num]}me; $subs[$num]=eval($t) or die "Failed to eval\n$t\n$@"; } sub demerphq { my ($len, @k) = @_; my ($a, $b, $c) = (0)x3; { ($len or last) and $a+= $k[0]; ($len >= 2 or last) and $a+= $k[1] <<8; ($len >= 3 or last) and $a+= $k[2] <<16; ($len >= 4 or last) and $a+= $k[3] <<24; ($len >= 5 or last) and $b+= $k[4]; ($len >= 6 or last) and $b+= $k[5] <<8; ($len >= 7 or last) and $b+= $k[6] <<16; ($len >= 8 or last) and $b+= $k[7] <<24; ($len >= 9 or last) and $c+= $k[8] <<8; ($len >= 10 or last) and $c+= $k[9] <<16; ($len >= 11 or last) and $c+= $k[10] <<24; } return ($a+$b+$c); } sub gotoit { my ($len, @k) = @_; my ($a, $b, $c) = (0)x3; goto "LAST".$len; LAST11: $c+= $k[10] <<24; LAST10: $c+= $k[9] <<16; LAST9: $c+= $k[8] <<8; LAST8: $b+= $k[7] <<24; LAST7: $b+= $k[6] <<16; LAST6: $b+= $k[5] <<8; LAST5: $b+= $k[4]; LAST4: $a+= $k[3] <<24; LAST3: $a+= $k[2] <<16; LAST2: $a+= $k[1] <<8; LAST1: $a+= $k[0]; LAST0: return ($a+$b+$c); } sub pfaut { my ($k) = @_; my ($a, $b, $c) = unpack 'L3', $k.(chr(0)x11) ; return ($a||0) + ($b||0) + ($c||0)<<8; } if ($time==1) { print 'template', $subs[$_]->((65) x $_),$/ for 0 ..11; print 'demerphq', demerphq( $_, (65) x $_),$/ for 0 .. 11; print 'gotoit' , gotoit( $_, (65) x $_),$/ for 0 .. 11; print 'pfaut' , pfaut( 'A' x $_),$/ for 0 .. 11; } else { cmpthese( $time, { template => q[$::subs[$_]->((65) x $_) for 0 ..11; ], demerphq => q[demerphq( $_, (65) x $_) for 0 .. 11;], gotoit => q[ gotoit( $_, (65) x $_) for 0 .. 11;], pfaut => q[ pfaut( 'A' x $_) for 0 .. 11;], }); } #### Benchmark: running demerphq, gotoit, pfaut, template, each for at least 10 CPU seconds... demerphq: 11 wallclock secs (10.52 usr) @ 4809.81/s (n=50580) gotoit: 10 wallclock secs (10.31 usr) @ 5002.33/s (n=51584) pfaut: 10 wallclock secs (10.52 usr) @ 9265.21/s (n=97433) template: 11 wallclock secs (10.56 usr) @ 5934.77/s (n=62689) Rate demerphq gotoit template pfaut demerphq 4810/s -- -4% -19% -48% gotoit 5002/s 4% -- -16% -46% template 5935/s 23% 19% -- -36% pfaut 9265/s 93% 85% 56% --