使用perl时调用是否map { function($_) } <FILEHANDLE>;
将整个文件加载到内存中?
问问题
1512 次
3 回答
6
是的——或者至少我是这样解释这个结果的。
$ perl -e "map {0} <>" big_data_file
Out of memory!
$ perl -e "map {0} 1 .. 1000000000"
Out of memory!
有人可能想知道我们是否会因为 Perl 试图存储map
. 然而,我的理解是 Perl 已经过优化,可以避免map
在 void 上下文中调用该工作。有关具体示例,请参阅此问题中的讨论。
也许是一个更好的例子:
$ 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>;
于 2011-05-22T15:14:45.987 回答
3
是的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 将原生支持惰性列表。
于 2011-05-23T02:54:35.827 回答
2
你要问的问题我假设是这样的:map
函数是在开始处理之前对文件进行 slurp,还是逐行使用。
让我们快速比较一下处理列表:
while (<FILEHANDLE>) { ... }
这个案例显然是逐行使用的。每次迭代,都会获取一个新值$_
。
for my $line (<FILEHANDLE>) { ... }
在这种情况下,LIST
在循环开始之前展开。在http://perldoc.perl.org/functions/map.html中有一个map
类似于foreach
循环的引用,我相信LISTs
在传递给函数之前会对其进行扩展。
于 2011-05-22T15:29:51.117 回答