I thought up another approach last night after I had logged out. It still isn't faster than pfauts, but it is an interesting example of using code templates.
#!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% --
TMTOWTDI

;-)

--- demerphq
my friends call me, usually because I'm late....


In reply to Re: Re: Re: Eek! goto? by demerphq
in thread Eek! goto? by BrowserUk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.