Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: Yet more While issues

by ikegami (Patriarch)
on Mar 16, 2011 at 19:22 UTC ( [id://893622]=note: print w/replies, xml ) Need Help??


in reply to Yet more While issues

For clarity more than for speed,

my $offset = splice @cPosns, rand @cPosns, 1;
should be
my $offset = $cPosns[rand @cPosns];
and
while (1) { ... last; }
should simply be
...

For speed, don't copy the zazb argument into a local variable. Access $_[3] directly.

A possible tweak:

push @cPosns, pos $zazb while $zazb =~ m{(?=c)}g;

might be faster as

push @cPosns, $-[0] while $zazb =~ m{c}g;

or maybe even

my $pos = -1; push @cPosns, $pos while ($pos = index($zazb, 'c', $pos+1)) >= 0;

Benchmark and find out.

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.

This will occur when 'c' doesn't occur in $zazb. Based on your first snippet, you want

sub popnum3 { my ( $x, $y, $z ) = @_; # $_[3] is $zazb if ( $y == 0 ) { $aob[$x][0] = $initial * ( 1 + $z ); } else { my @cPosns; push @cPosns, $-[0] while $_[3] =~ m{c}g; if (@cPosns) { my $offset = $cPosns[rand @cPosns]; $aob[$x][$y] = $aob[$offset][ $y - 1 ] * ( 1 + $z ); } } return $aob[$x][$y]; }

Replies are listed 'Best First'.
Re^2: Yet more While issues
by Dandello (Monk) on Mar 16, 2011 at 22:04 UTC

    I got it - at least it's stopped throwing warnings and it's a whole lot faster that what I had before.

    Since popnum3 is called from inside an if/else

    else { my $pos = -1; push @cPosns, $pos while ($pos = index($zazb, 'c', $pos+1)) >= 0; my $offset = $cPosns[rand @cPosns]; $cell = sprintf '%.2f', popnum3( $x, $y, $copycop, $offset, ); }
    then
    sub popnum3 { my ( $x, $y, $z, $offset ) = @_; if ( $y == 0 ) { $aob[$x][0] = $initial * ( 1 + $z ); } else { while (1) { $aob[$x][$y] = $aob[$offset][ $y - 1 ] * ( 1 + $z ); last; } } return $aob[$x][$y]; }

    So far it's looking good. Thanks

      What's with the useless while(1) { ...; last; } again?

        Habit

        I'm still trying to get everything configured to work right - When I have the code set up like this:

        else { my $pos = -1; push @cPosns, $pos while ($pos = index($zazb, 'c', $pos+1)) >= 0; my $offset = $cPosns[rand @cPosns]; $cell = sprintf '%.2f', popnum3( $x, $y, $copycop, $offset, ); }
        then
        sub popnum3 { my ( $x, $y, $z, $offset ) = @_; if ( $y == 0 ) { $aob[$x][0] = $initial * ( 1 + $z ); } else { while (1) { $aob[$x][$y] = $aob[$offset][ $y - 1 ] * ( 1 + $z ); last; } } return $aob[$x][$y]; }
        It's reiterating over the entire string for every single 'a' or 'c' which starts fast then slows to a crawl

        When I move this section

        my $pos = -1; push @cPosns, $pos while ($pos = index($zazb, 'c', $pos+1)) >= 0;
        above all the if/else's, to just under where $zazb is defined, then the $offset variable in
        else { my $offset = $cPosns[rand @cPosns]; $cell = sprintf '%.2f', popnum3( $x, $y, $copycop, $offset, ); }
        becomes undefined when imported into popnum3.

        So obviously I'm still missing something.

        There is always at least 1 'c' in the string so that's not the problem.

Re^2: Yet more While issues
by Dandello (Monk) on Mar 18, 2011 at 05:20 UTC

    Back to square one I guess. This

    sub popnum3 { my ( $x, $y, $z ) = @_; # $_[3] is $zazb if ( $y == 0 ) { $aob[$x][0] = $initial * ( 1 + $z ); } else { my @cPosns; push @cPosns, $-[0] while $_[3] =~ m{c}g; if (@cPosns) { my $offset = $cPosns[rand @cPosns]; $aob[$x][$y] = $aob[$offset][ $y - 1 ] * ( 1 + $z ); } } return $aob[$x][$y]; }
    only seems to work relatively short strings, but not when the string gets much more than 500 characters. Then it throws 'uninitialized value in $offset' errors which I'm guessing means the algorithm didn't find the one 'c' that had to be there.

    I admit I'm at my wit's end here. This looks like it should work, but it doesn't. There is a 'c' in every row, so that's not the problem.

    THIS works

    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]; }
    But takes about 5 seconds per row on the full array and since there's 8400 rows in the full run, that's about 12 hours.

    Getting the run time down would be very helpful.

    Thanks

      Then it throws 'uninitialized value in $offset' errors

      I don't believe you when you say that snippet produced that warning.

      Then it throws 'uninitialized value in $offset' errors which I'm guessing means the algorithm didn't find the one 'c' that had to be there.

      No. If it doesn't find any 'c', it never uses $offset.

      PS - Don't count out half the warning (not even counting the line number).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://893622]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2024-04-23 14:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found