What's the difference, from the interpreter's POV, between the following the following programs:
#!/usr/bin/perl -w
use strict;
for (1..10000000) {
my $jimmy = $_**2;
}
and
#!/usr/bin/perl -w
use strict;
my $jimmy;
for (1..10000000) {
$jimmy = $_**2;
}
"time" reports for the first program:
real 0m1.519s
user 0m1.513s
sys 0m0.004s
and for the second:
real 0m1.023s
user 0m1.012s
sys 0m0.002s
It's not a problem to define a variable within a loop. In fact, it's good practice, since identifiers should be confined to the smallest possible scope. What's bad is to assign a variable within a loop if you could just as well assign it once before the loop runs.
All the variables which are used in the program are declared in the beginning. It is better to declare the variable in the loop as its validity will be only up to that block and the code can stand alone for that section. So, to tell there is no difference in anything if either of the approaches are used.
The difference is the scope of the variables. In case you define the variable outside of the loop in can be accessed in a bigger scope.
every statement in Perl must end with a semicolon(;).
The my
declaration in Perl has two primary effects; a compile-time one (wherein it allocates a slot on the containing sub's scratchpad, and makes sure that all references to that name within the proper scope are resolved to that particular scratchpad slot), and a runtime one (wherein it resets the value of that pad slot to undef
, or to some particular value if you wrote my $var = foo
).
The compile-time portion of course has zero amortized runtime cost, but the runtime portion is run once each time execution passes the my declaration. As others have pointed out, your two examples have different performance because they have different semantics in general -- one clears the variable every time through the loop, and the other doesn't.
Since the example programs you have given do not really do anything it is hard to give you a specific reason why one type of declaration would be better than the other. As many other posters have pointed out, declaring the variable in the loop creates a new variable each time. In your examples that creation is redundant, but consider the following examples using closures.
my @closures;
my $jimmy;
for (1 .. 10) {
$jimmy = $_** 2;
push @closures, sub {print "$jimmy\n"};
}
and this one:
my @closures;
for (1 .. 10) {
my $jimmy = $_** 2;
push @closures, sub {print "$jimmy\n"};
}
In each case the code builds up a series of code references, but in the first example since all the code refs refer to the same $jimmy
each one will print 100 when called. In the second example each code ref will print a different number (1, 4, 9, 16, 25, ...)
So in this case the time difference does not really matter since the two blocks of code do very different things.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With