В большинстве случаев вы, вероятно, не заметите разницу. Однако foreach
считывает каждую строку в список (, а не массив ), прежде чем проходить по ней построчно, тогда как while
читает по одной строке за раз. Поскольку foreach
будет использовать больше памяти и потребовать времени обработки заранее, обычно рекомендуется использовать while
для перебора строк файла.
РЕДАКТИРОВАТЬ (через Шверн): цикл foreach
эквивалентен этому:
my @lines = <$fh>;
for my $line (@lines) {
...
}
К сожалению, Perl не оптимизирует этот особый случай, как это происходит с оператором диапазона (1..10
).
Например, если я читаю / usr / share / dict / words с циклом for
и циклом while
и заставляет их спать, когда они закончат, я могу использовать ps
, чтобы увидеть, сколько памяти процесс потребляет. В качестве контроля я включил программу, которая открывает файл, но ничего с ним не делает.
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
schwern 73019 0.0 1.6 625552 33688 s000 S 2:47PM 0:00.24 perl -wle open my $fh, shift; for(<$fh>) { 1 } print "Done"; sleep 999 /usr/share/dict/words
schwern 73018 0.0 0.1 601096 1236 s000 S 2:46PM 0:00.09 perl -wle open my $fh, shift; while(<$fh>) { 1 } print "Done"; sleep 999 /usr/share/dict/words
schwern 73081 0.0 0.1 601096 1168 s000 S 2:55PM 0:00.00 perl -wle open my $fh, shift; print "Done"; sleep 999 /usr/share/dict/words
Программа for
потребляет почти 32 мегабайта реальной памяти (столбец RSS
) для хранения содержимого моих 2,4 мегабайт / usr / share / dict / words. Цикл while
хранит только одну строку за раз, затрачивая всего 70 Кб для буферизации строки.