Когда вы делаете:
my @lines = <FOO>;
, вы создаете массив с таким количеством элементов, сколько строк в file
.При 100 символах в строке это около 3,4 миллиона записей массива.С каждой записью массива связаны накладные расходы, что означает, что объем занимаемой памяти будет намного больше, чем просто размер несжатого файла.
Вы можете избежать расплывчатости и обрабатывать файл построчно.Вот пример:
C:\Temp> dir file
2010/10/04 09:18 PM 328,000,000 file
C:\Temp> dir file.gz
2010/10/04 09:19 PM 1,112,975 file.gz
И, действительно,
#!/usr/bin/perl
use strict; use warnings;
use autodie;
use PerlIO::gzip;
open my $foo, '<:gzip', 'file.gz';
while ( my $line = <$foo> ) {
print ".";
}
не имеет проблем.
Чтобы получить представление об объеме памяти, обратите внимание:
#!/usr/bin/perl
use strict; use warnings;
use Devel::Size qw( total_size );
my $x = 'x' x 100;
my @x = ('x' x 100);
printf "Scalar: %d\n", total_size( \$x );
printf "Array: %d\n", total_size( \@x );
Вывод:
Scalar: 136
Array: 256