Использование памяти Perl с картой и дескриптором файла - PullRequest
6 голосов
/ 22 мая 2011

Загружает ли map { function($_) } <FILEHANDLE>; весь файл в память при использовании perl?

Ответы [ 3 ]

6 голосов
/ 22 мая 2011

Да - или, по крайней мере, так я интерпретирую этот результат.

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

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

Можно задаться вопросом, не хватает ли памяти, потому что Perl пытается сохранить вывод map. Тем не менее, я понимаю, что Perl оптимизирован, чтобы избежать этой работы всякий раз, когда map вызывается в пустом контексте. Для конкретного примера см. Обсуждение в этот вопрос .

Возможно, лучший пример :

$ 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>;
3 голосов
/ 23 мая 2011

Да, операнды для map, цикл foreach и дополнительные вызовы оцениваются до map, цикл 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 голосов
/ 22 мая 2011

Вопрос, который вы задаете, я предполагаю, заключается в следующем: выполняет ли функция map файл перед тем, как начать обработку, или использует строку за строкой.

Позволяет сделать быстрое сравнение со списками:

while (<FILEHANDLE>) { ... }

Этот случай явно использует построчно.На каждой итерации выбирается новое значение для $_.

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

В этом случае LIST расширяется до начала цикла.В http://perldoc.perl.org/functions/map.html есть ссылка на map, похожую на цикл foreach, и я верю, что LISTs расширяется перед передачей в функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...