Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: redeclaring variables with 'my'

by Fastolfe (Vicar)
on Nov 10, 2000 at 19:19 UTC ( [id://40953]=note: print w/replies, xml ) Need Help??


in reply to redeclaring variables with 'my'

Usually I tend to back out when my own knowledge seems to differ when the majority, but just for the record, my understanding agrees with this guy's guru's. These two while loops are not equivalent (and not for the reasons you think):
# within while (my $x = $count) { $count++; last if $count >= 5000000; } # without my $x; while ($x = $count) { $count++; last if $count >= 5000000; } Benchmark: timing 10 iterations of within, without... within: 40 wallclock secs (39.78 usr + 0.04 sys = 39.82 CPU) @ 0 +.25/s (n=10) without: 35 wallclock secs (35.09 usr + 0.00 sys = 35.09 CPU) @ 0 +.28/s (n=10)
Now, I'm no expert on Perl internals, but it certainly seems like $x is being re-allocated for every loop. At a minimum, $x falls out of scope when the loop ends, which leads me to believe it's falling out of scope for each iteration and being re-allocated. Note that it isn't being redeclared, just reallocated. I'd be interested if anyone has any other explanation...

Replies are listed 'Best First'.
RE (tilly) 2: redeclaring variables with 'my'
by tilly (Archbishop) on Nov 11, 2000 at 02:30 UTC
    There is some run-time action upon entering and exiting its scope, so there is indeed some overhead. It does not need to allocate and deallocate space, but Perl does need to manipulate reference counts and check that the old space allocated is for a variable not in use and so can be reassigned. (Just in case you saved a reference and kept a closure!) But even within this minimal loop the overhead is minor.

    So yes, there is a small amount of overhead associated with the safer mechanism. However when you try conciously switching styles between projects you will quickly find that the safer style results in big wins in terms of reliability, development, and debugging. Besides which, aggressively modularizing your code etc gives you opportunities to later find and fix large algorithm mistakes. (Leading to better performance wins than optimizing the heck out of your code up front can do.)

    The tiny performance difference is a really, really bad excuse for keeping a bad habit. For more on this topic, there is a sample section from Code Complete online.

      I agree completely, and have been reluctant to move away from the while (my $var ...) style for that reason (except in cases where I'm expecting to iterate very tightly many thousands of times). A 15% win isn't much when we're talking about, like, picoseconds here. Heh.
RE: Re: redeclaring variables with 'my'
by btrott (Parson) on Nov 11, 2000 at 02:35 UTC
    It's not re-allocating memory each time through the loop. You can test that by doing this:
    my $count = 1; while (my $x = $count) { print \$x, "\n"; last if ++$count > 5; }
    If you run that, you should get something like:
    SCALAR(0x80e4aa8) SCALAR(0x80e4aa8) SCALAR(0x80e4aa8) SCALAR(0x80e4aa8) SCALAR(0x80e4aa8)
    Each time through the loop $x is at the same memory location. So it's not re-allocating memory.

    As tilly mentions in his post, Perl does have to do *some* extra things--but re-allocating memory isn't one of them. :)

      If it were tightly de-allocating and re-allocating, is it not unreasonable to expect that they might end up at the same address? Not that I disagree with you; I'm hardly the expert. I rather think that what you say is actually the case.

      But yah, I think tilly's hit it on the head.

        It would be reasonable, but it doesn't work that way. In fact here is a piece of code that triggers an illustrative bug in how it does work:
        recurse_lex(1); print "\n"; recurse_lex(2); print "\n"; recurse_lex(3); print "\n"; recurse_lex(4); print "\n"; sub recurse_lex { my $i = shift; my @array if 0; unshift @array, $i; print @array, "\n"; $i--; if ($i) { recurse_lex($i); } }
        Try that. It does something weird. And here are the details of what does happen.
RE: Re: redeclaring variables with 'my'
by extremely (Priest) on Nov 11, 2000 at 03:16 UTC
    You are correct Fastolfe, the re-allocation happens in the loop. However, this is the behavior that is GOOD. The cost of the allocation is a great deal less than this
    my $x='ok'; # scads of code my $x=300; while ($x--) { do_something_with($x); } # scads of code... print "$final" if ($x eq 'ok'); #kaboom

    In the end, when you do a "-w" and it complains that '$x won't stay shared' or something at the second my, your lesser perl wizard is likely to take the "my" off since the variable is already declared. Ouch.

    In the end, you suffer the cost of extra work on the backside to protect yourself from the future.

    --
    $you = new YOU;
    honk() if $you->love(perl)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2024-03-29 11:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found