在for循环中声明变量不好?

CJ7*_*CJ7 2 perl memory-leaks declaration

for $i (1..1000000)
{
    my $a = rand(10);
    my $b = rand(10);
    my $c = rand(10);
}
Run Code Online (Sandbox Code Playgroud)

将上面的代码分配用于新的存储位置$a,$b$c循环的每次迭代期间,从而使用起来更内存比下面的代码?

my ($a,$b,$c);
for $i (1..1000000)
{
    $a = rand(10);
    $b = rand(10);
    $c = rand(10);
}
Run Code Online (Sandbox Code Playgroud)

mel*_*ene 5

(首先,$i不应该是一个全局变量,所以这应该是for my $i (...)二,不使用名称$a$b,甚至没有在例子中,因为它们是通过使用特殊的变量sort.)

这个问题的天真答案是否定的,因为$a,$b并且$c在到达块的末尾时被释放},因此迭代的最终结果是内存使用的零变化.

perl中的实际实现更加智能:它为$a/ $b/ 重用内存,$c因此它不必重复释放然后重新分配同一块内存.(当然,如果你创建一个对循环体之外的局部变量的引用,它就不能这样做,因为这个变量保持活着,即使它的名字超出了范围.)

您可以通过将循环更改为此来确认是这种情况:

for my $i (1 .. 5) {
    my $x = rand 10;
    my $y = rand 10;
    my $z = rand 10;
    print join(" ", \$x, \$y, \$z), "\n";
}
Run Code Online (Sandbox Code Playgroud)

输出将是类似的

SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)
SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)
SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)
SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)
SCALAR(0x4a5788) SCALAR(0x4a5728) SCALAR(0x4a56c8)
Run Code Online (Sandbox Code Playgroud)

这表明存储器位置在所有循环迭代中都是相同的.