Well, sort of
I'm trying to speed up a subroutine by going from this
Which gets - for obvious reasons - REALLY slow on large strings, to something like this:sub popnum3 { my ( $x, $y, $z, $zazb ) = @_; if ( $y == 0 ) { $aob[$x][0] = $initial * ( 1 + $z ); } else { while (1) { my $xda = int rand( $total + 1 ); if ( substr( $zazb, $xda, 1 ) eq 'c' ) { $aob[$x][$y] = $aob[$xda][ $y - 1 ] * ( 1 + $z ); last; } } } return $aob[$x][$y]; }
Which I just can't seem to get my head around to get it to work without throwing 'undefined value' warnings all over the place.sub popnum3 { my ( $x, $y, $z, $zazb ) = @_; if ( $y == 0 ) { $aob[$x][0] = $initial * ( 1 + $z ); } else { while (1) { my @cPosns; push @cPosns, pos $zazb while $zazb =~ m{(?=c)}g; my $offset = splice @cPosns, rand @cPosns, 1; $aob[$x][$y] = $aob[$offset][ $y - 1 ] * ( 1 + $z ); last; } } return $aob[$x][$y]; }
For both these, $x and $y are 2d array references, $z is a predetermined random number and $zazb is a string containing a more or less random number of 'a's, 'c's, 'y's and 'x's (and may be over than 25,000 characters long). This subroutine is supposed to locate one of the 'c's in $zazb, (without iterating over the entire string repeatedly) grab its mate from the @aob array (which is a number) and determine the value of $aob[$x][$y] based on the value of 'c's mate.
This code
is adapted from http://www.perlmonks.org/?node_id=891330my @cPosns; push @cPosns, pos $zazb while $zazb =~ m{(?=c)}g; my $offset = splice @cPosns, rand @cPosns, 1;
Update
Despite ikegami's input, I still can't get anything even closely related to the above code to work for this instance. However, since the parameters of the model data has changed, it's no longer an issue as all the indexes for 'c' need to saved to a file for data-munging.
So, this does a good and fast job finding the indices for 'c' from @aod (the array of strings containing 'c'.)
then for the random indexes ($off is the array of 'c' indices.)tie my @aod, 'Tie::File', 'bias/array.txt', recsep => "\n"; my $letter = 'c'; my $result = 0; open my $DATABASE, '>', $datafileout or croak 'dataout not made.'; foreach my $r (0 .. $gener){ $result = index($aod[$r], $letter); while ($result != -1){ print {$DATABASE} qq{$result,}; my $offset = $result + 1; $result = index($aod[$r], $letter, $offset); } print {$DATABASE} qq{\n} or croak 'unable to print'; } close $DATABASE or croak 'data1 not closed.';
then to get the random offsetmy @offst = split /\,/xsm, $off[$y - 1];
It may not be pretty - but it does work.my $index = int rand ($#offst); $offset = $offst[$index];
In reply to Yet more While issues by Dandello
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |