Perl内存使用与地图和文件句柄

时间:2011-05-22 14:58:09

标签: perl file map memory-management filehandle

使用perl时,调用map { function($_) } <FILEHANDLE>;是否将整个文件加载到内存中?

3 个答案:

答案 0 :(得分:6)

是 - 或者至少我是如何解释这个结果的。

$ perl -e "map {0} <>" big_data_file
Out of memory!

$ perl -e "map {0} 1 .. 1000000000"
Out of memory!

有人可能会怀疑我们是否因为Perl试图存储map的输出而耗尽内存。但是,我的理解是Perl已经过优化,可以在void上下文中调用map时避免这种工作。有关具体示例,请参阅this question中的讨论。

也许是更好的例子

$ perl -e "sub nothing {}  map nothing(), <>" big_data_file
Out of memory!

根据评论,似乎问题的动机是在处理大数据时需要紧凑的语法。

open(my $handle, '<', 'big_data_file') or die $!;

# An ordinary while loop to process a data file.
while (my $line = <$handle>){
    foo($line);
}

# Here Perl assigns each line to $_.
while (<$handle>){
    foo($_);
}

# And here we do the same thing on one line.
foo($_) while <$handle>;

答案 1 :(得分:3)

是的,在map之前评估map,foreach循环和子调用的操作数,foreach循环或子调用甚至开始。

一个例外:

for my $i (EXPR_X..EXPR_Y)

(有或没有my $i)被优化为计数循环,类似于

my $x = EXPR_X;
my $y = EXPR_Y;
for (my $i = $x; $i <= $y; ++$i)

Perl6将支持懒惰列表。

答案 2 :(得分:2)

您要问的问题我是这样的:map函数在开始处理之前是否会淹没文件,或者是否逐行使用。

让我们快速比较一下处理清单:

while (<FILEHANDLE>) { ... }

这个案例清楚地逐行使用。每次迭代时,都会获取$_的新值。

for my $line (<FILEHANDLE>) { ... }

在这种情况下,LIST在循环开始之前展开。在http://perldoc.perl.org/functions/map.html中,有map类似于foreach循环的引用,我相信LISTs在传递给函数之前会被展开。