in reply to (duplicate) Eek! goto?

$k is not manipulated during the course of that block, and all operations are additions, with which order does not matter. So you could reverse the order of operations and bail early from the block upon a counter reaching $len, rather than skip the first 11-$len instructions.
{ last if $len == 0; $a+= $k[0]; last if $len == 1; $a+= $k[1] <<8; last if $len == 2; $a+= $k[2] <<16; last if $len == 3; $a+= $k[3] <<24; last if $len == 4; $b+= $k[4]; last if $len == 5; $b+= $k[5] <<8; last if $len == 6; $b+= $k[6] <<16; last if $len == 7; $b+= $k[7] <<24; last if $len == 8; $c+= $k[8] <<8; last if $len == 9; $c+= $k[9] <<16; last if $len == 10; $c+= $k[10] <<24; }
Admittedly very redundant and not very graceful. Let's look at this another way: you have a basically data driven design here: the target and shift factor depends on the index. So not write it that way?
my @targ_shift = ( [ \$a, 0 ], [ \$a, 8 ], [ \$a, 16 ], [ \$a, 24 ], [ \$b, 0 ], [ \$b, 8 ], [ \$b, 16 ], [ \$b, 24 ], [ \$c, 8 ], [ \$c, 16 ], [ \$c, 24 ], ); for my $idx (0 .. $len-1) { my ($targ, $shift) = @{$targ_shift[$idx]}; $$targ += $k[$idx] << $shift; }
or maybe
{ my @targ_shift = ( \$a, 0, \$a, 8, \$a, 16, \$a, 24, \$b, 0, \$b, 8, \$b, 16, \$b, 24, \$c, 8, \$c, 16, \$c, 24, ); for (0 .. $len-1) { my ($targ, $shift) = splice @targ_shift, 0, 2; $$targ += $k[$_] << $shift; } }
"Capture regularities in code, irregularities in data", the koan of the senior programmer as merlyn so aptly put it.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re: Eek! goto?
by BrowserUk (Patriarch) on Feb 19, 2003 at 13:57 UTC

    Your first one is essentially similar to demerphq's suggestion at Re: Eek! goto?--which you quite possibly didn't see as I managed to create two root nodes that despite my considering one for deletion, both continue existing.

    The other two are neat, but do you need splice in the latter? Wouldn't this work?

    for (0 .. $len-1) { $$targ_shift[$_] += $k[$targ_shift[$_+1]] << $shift; }

    The downside is speed. If you look at the original C-code you'll see that the whole reason for the switch was to allow a loop to be unwound for performance reasons. In the end, pfaut's realisation that basically the code is unpacking an unsigned long int which lead to the sub hash2() as shown at Re: Re: Eek! goto? using unpack. It came out hands-down winner for performance and I went with that in the end.


    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

      Well no, it would be
      for (0 .. $len-1) { $$targ_shift[$_*2] += $k[$_] << $targ_shift[$_*2+1]; }

      Makeshifts last the longest.