"My" memory overwrite when called in a loop?
Simple but relevant question: "my" memory overwrite when called in a loop?
For example, it is "better" (in terms of memory leaks, performance, speed) to declare it outside the loop:
my $variable;
for my $number ( @array ) {
$variable = $number * 5;
_sub($variable);
}
Or should I declare it inside the loop:
for my $number ( @array ) {
my $variable = $number * 5;
_sub($variable);
}
(I just did this code, it didn't want to do or use anything - as it is - in real life)
Will Perl allocate new memory space for each iteration for iterations?
source to share
Aamir has already told you what will happen.
I recommend sticking with the second version unless there is a reason to use the first. You don't want to worry about the previous condition $variable
. The easiest way is to start each iteration with a fresh variable. And if the variable contains a reference, you can shoot yourself in the foot if you push it to the array.
Edit:
Yes, there is a performance hit. Using the recycled variable will be faster. However, heck, how much faster it will be, as it will depend on your specific situation. No matter how much faster it happens, always remember: Premature optimization is the root of all evil .
source to share
These are things you shouldn't be thinking about with a dynamic language like Perl. Even if you can get an answer as to what the current implementation is doing, it is not a function and you should not rely on it.
Define your variables in the shortest scope possible.
However, to be just curious, you can use the Devel :: Peek module to cheat a little to see the inner (not physical):
use Devel::Peek;
foreach ( 0 .. 5 ) {
my $var = $_;
Dump( $var );
}
In this small case, the address ends up being the same. This does not guarantee that it will always be the same for different situations or even the same program:
SV = IV (0x9ca968) at 0x9ca96c REFCNT = 1 FLAGS = (PADMY, IOK, pIOK) IV = 0 SV = IV (0x9ca968) at 0x9ca96c REFCNT = 1 FLAGS = (PADMY, IOK, pIOK) IV = 1 SV = IV (0x9ca968) at 0x9ca96c REFCNT = 1 FLAGS = (PADMY, IOK, pIOK) IV = 2 SV = IV (0x9ca968) at 0x9ca96c REFCNT = 1 FLAGS = (PADMY, IOK, pIOK) IV = 3 SV = IV (0x9ca968) at 0x9ca96c REFCNT = 1 FLAGS = (PADMY, IOK, pIOK) IV = 4 SV = IV (0x9ca968) at 0x9ca96c REFCNT = 1 FLAGS = (PADMY, IOK, pIOK) IV = 5
source to share
You can compare the difference between these two uses with the Benchmark module that is generated for these types of comparisons using micro-benchmarking:
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw( cmpthese );
sub outside {
my $x;
for my $y ( 1 .. 1_000_000 ) {
$x = $y;
}
return;
}
sub inside {
for my $y ( 1 .. 1_000_000 ) {
my $x = $y;
}
return;
}
cmpthese -1 => {
inside => \&inside,
outside => \&outside,
};
Results on my Windows XP SP3 laptop:
Rate inside outside inside 4.44 / s - -25% outside 5.91 / s 33% -
As expected, the difference is less pronounced when the loop body is only executed once.
However, I would not declare $x
outside the loop unless I needed outside of the loop what is assigned $x
inside the loop.
source to share
You are completely safe using "mine" inside a for loop or any other block. In general, you don't need to worry about memory leaks in perl, but in this case, you will be equally safe with a non-garbage-related language like C ++. A normal variable is freed at the end of the block in which it has scope.
source to share