使用perl时,调用map { function($_) } <FILEHANDLE>;
是否将整个文件加载到内存中?
答案 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
在传递给函数之前会被展开。