in reply to Getting a list of aliases to selected items from a list of array references

if( 0 == @_ ) { &$sub(); } elsif( 1 == @_ ) { &$sub( $_[0][0] ); } elsif( 2 == @_ ) { &$sub( $_[0][0], $_[1][0] ); } elsif( 3 == @_ ) { &$sub( $_[0][0], $_[1][0], $_[2][0] ); # etc to some arbitrary maximum number of arguments }
and that lead me to realize that I could get what I want using eval:     eval "&\$sub( " . join( ", ", map "\$_[$_][0]", 0..$#_ ) . " )"
You could do (untested, and probably some experimentation needed to find a good cutoff point):
if ($#_ <= 255) { my $lim = $#_; &$sub(($_[0][0],$_[1][0],$_[2][0],$_[3][0],$_[4][0], $_[5][0],$_[6][0],$_[7][0],$_[8][0],$_[9][0], ... $_[255] )[0..$lim]); $#_ = $lim # remove autovivified arrayrefs } else { eval "&\$sub( " . join( ", ", map "\$_[$_][0]", 0..$#_ ) . " )"; }

Replies are listed 'Best First'.
Re^2: Getting a list of aliases to selected items from a list of array references (unroll)
by tye (Sage) on May 17, 2004 at 03:06 UTC

    Sort of combining this idea with my idea, I could unroll the loop, perhaps reducing the performance penalty (or perhaps not):

    my $aPush= sub { \@_ }; my $av= []; while( 9 < @_ ) { $av= $aPush->( @$av, $_[0][0], $_[1][0], $_[2][0], $_[3][0], $_[4][0], $_[5][0], $_[6][0], $_[7][0], $_[8][0], $_[9][0] + ); splice @_, 0, 10; } while( 2 < @_ ) { $av= $aPush->( @$av, $_[0][0], $_[1][0], $_[2][0] ); splice @_, 0, 3; } $av= $aPush->( @$av, $_->[0] ) for @_;

    or combine more of your idea in but still not need string eval...

    - tye        

      I don't like thrashing @_ because I'm weird, so how about something like this?

      my $aPush = sub { \@_ }; my $av = []; for (my $index = 0;$index < @_; $index += 16) { my $length = $#_ - $index; $av = $aPush->(@$rv, ($_[$index][0],$_[$index+1][0], $_[$index+2][0],$_[$index+3][0],$_[$index+4][0], $_[$index+5][0],$_[$index+6][0],$_[$index+7][0], $_[$index+8][0],$_[$index+9][0],$_[$index+10][0], $_[$index+11][0],$_[$index+12][0],$_[$index+13][0], $_[$index+14][0],$_[$index+15][0] )[ 0..($length < 16 ? $length:15) ] ); }

      Update: After benchmarking this against what you have in the previous post, yours is definitely faster.

      antirice    
      The first rule of Perl club is - use Perl
      The
      ith rule of Perl club is - follow rule i - 1 for i > 1