【发布时间】:2011-08-30 15:08:30
【问题描述】:
在使用 perl 时调用map { function($_) } <FILEHANDLE>; 是否会将整个文件加载到内存中?
【问题讨论】:
标签: perl file map memory-management filehandle
在使用 perl 时调用map { function($_) } <FILEHANDLE>; 是否会将整个文件加载到内存中?
【问题讨论】:
标签: perl file map memory-management filehandle
是的——或者至少我是这样解释这个结果的。
$ 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!
根据 cmets,问题的动机似乎是在处理大数据时希望使用紧凑的语法。
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>;
【讨论】:
0 值的列表。如果您使用 for 循环并将 push 归零到数组上,您将得到相同的错误。虽然在那种情况下,它不是瞬时的。
map { print FILEHANDLE function($_) } <FILEHANDLE>;。我只是更喜欢在小型操作上使用 map 而不是 foreach。
print FILEHANDLE function($_) while <FILEHANDLE>;。
是的,map、foreach 循环和 sub 调用的操作数在 map 之前计算,foreach 循环或 sub 调用甚至开始。
一个例外:
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 将原生支持惰性列表。
【讨论】:
f(),参数是操作数。
我假设您要问的问题是:map 函数是在文件开始处理之前对文件进行 slurp,还是逐行使用。
让我们快速比较一下处理列表:
while (<FILEHANDLE>) { ... }
这个案例显然是逐行使用的。每次迭代都会获取$_ 的新值。
for my $line (<FILEHANDLE>) { ... }
在这种情况下,LIST 在循环开始之前被展开。在http://perldoc.perl.org/functions/map.html 中有一个对map 的引用,类似于foreach 循环,我相信LISTs 在传递给函数之前会被扩展。
【讨论】:
map { print FILEHANDLE function($_) } <FILEHANDLE>; 编辑:它似乎确实将文件加载到内存中(参见 FMc 的答案),所以我将使用 foreach 循环而不是地图。