我有一个310MB大小的文本文件(未压缩).当使用PerlIO :: gzip打开文件并将其解压缩到内存中时,在perl内存不足之前,此文件很容易填充2GB的RAM.
该文件打开如下:
open FOO, "<:gzip", "file.gz" or die $!;
my @lines = <FOO>;
Run Code Online (Sandbox Code Playgroud)
显然,这是一种在perl中轻松打开gzip文件的超级便捷方式,但它占用了大量的空间!我的下一步是将文件解压缩到HD,将文件行读取到@lines,在@lines上操作,然后将其压缩.有没有人知道为什么打开压缩文件时消耗的内存超过7倍?有没有人有一个替代的想法,我怎么能解压缩这个gzip文件到内存而不占用大量的内存?
raf*_*afl 22
您正在将文件的所有内容读入@lines数组.当然,这会将所有未压缩的内容拉入内存.您可能想要的是逐行读取句柄,只在内存中保留一行:
open my $foo, '<:gzip', 'file.gz' or die $!;
while (my $line = <$fh>) {
# process $line here
}
Run Code Online (Sandbox Code Playgroud)
Sin*_*nür 17
当你这样做时:
my @lines = <FOO>;
Run Code Online (Sandbox Code Playgroud)
你正在创建一个数组,其元素与行数一样多file.每行100个字符,大约有340万个数组条目.每个数组条目都存在开销,这意味着内存占用量将远大于文件的未压缩大小.
您可以逐行避免诽谤和处理文件.这是一个例子:
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 ".";
}
Run Code Online (Sandbox Code Playgroud)
没有问题.
要了解内存开销,请注意:
#!/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 );
Run Code Online (Sandbox Code Playgroud)
输出:
Scalar: 136 Array: 256