map { function($_) } <FILEHANDLE>;
perlを使用する場合、呼び出しはファイル全体をメモリにロードしますか?
3 に答える
はい、少なくとも私はこの結果をそのように解釈しています。
$ perl -e "map {0} <>" big_data_file
Out of memory!
$ perl -e "map {0} 1 .. 1000000000"
Out of memory!
Perl が の出力を保存しようとしているために、メモリが不足しているのではないかと思う人もいるかもしれませんmap
。map
ただし、私の理解では、Perl はが無効なコンテキストで呼び出されるたびにその作業を回避するように最適化されています。具体的な例については、この質問の説明を参照してください。
おそらくより良い例:
$ 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>;
はい、 for map
、 foreach ループ、および sub 呼び出しのオペランドは、 foreach ループまたは sub 呼び出しが始まる前に評価されmap
ます。
1 つの例外:
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 は遅延リストをネイティブでサポートします。
あなたが私が推測している質問はこれです:map
関数は処理を開始する前にファイルを丸呑みしますか、それとも行ごとに使用しますか?
リストの処理について簡単に比較してみましょう。
while (<FILEHANDLE>) { ... }
この場合は明らかに行ごとに使用されます。反復ごとに、の新しい値$_
がフェッチされます。
for my $line (<FILEHANDLE>) { ... }
この場合、LIST
ループが開始する前にが展開されます。http://perldoc.perl.org/functions/map.htmlにはmap
、ループに似ているという参照があり、関数に渡される前に展開されるforeach
と思います。LISTs