Performance 使用Perl压缩文件的最佳方法是什么?

Performance 使用Perl压缩文件的最佳方法是什么?,performance,perl,gunzip,Performance,Perl,Gunzip,有没有比我用Perl编写的gunzip文件的实际“zcat”解决方案更快的解决方案 一个小基准: #!/usr/bin/perl use strict; use warnings; use Benchmark qw(cmpthese timethese); use IO::Uncompress::Gunzip qw(gunzip); my $re = qr/test/; my $bench = timethese($ARGV[1], { zcat => sub { if

有没有比我用Perl编写的gunzip文件的实际“zcat”解决方案更快的解决方案

一个小基准:

#!/usr/bin/perl

use strict;
use warnings;
use Benchmark qw(cmpthese timethese);
use IO::Uncompress::Gunzip qw(gunzip);

my $re = qr/test/;

my $bench = timethese($ARGV[1], {

  zcat => sub {
    if (defined open(my $FILE, "-|", "zcat " . $ARGV[0]))
    {
      while (<$FILE>)
      {
        print $_  if ($_ =~ $re);
      }
      close($FILE);
    }
  },

  io_gunzip => sub {
    my $z = new IO::Uncompress::Gunzip $ARGV[0];
    while (<$z>)
    {
      print $_  if ($_ =~ $re);
    }
  },

  io_gunzip_getline => sub {
    my $z = new IO::Uncompress::Gunzip $ARGV[0];
    while (my $line = $z->getline())
    {
      print $line if ($line =~ $re);
    }
  },

} );

cmpthese $bench;

1;
#!/usr/bin/perl

use strict;
use warnings;
use Benchmark qw(cmpthese timethese);
use IO::Uncompress::Gunzip qw(gunzip);
use PerlIO::gzip;

my $re = qr/test/;

my $bench = timethese($ARGV[1], {

  zcat => sub {
    if (defined open(my $FILE, "-|", "zcat " . $ARGV[0]))
    {
      while (<$FILE>)
      {
        print $_  if ($_ =~ $re);
      }
      close($FILE);
    }
  },

  io_gunzip => sub {
    my $z = new IO::Uncompress::Gunzip $ARGV[0];
    while (<$z>)
    {
      print $_  if ($_ =~ $re);
    }
  },

  io_gunzip_getline => sub {
    my $z = new IO::Uncompress::Gunzip $ARGV[0];
    while (my $line = $z->getline())
    {
      print $line if ($line =~ $re);
    }
  },

  perlio_gzip => sub {
    if (defined open(my $FILE, "<:gzip", $ARGV[0]))
    {
      while (<$FILE>)
      {
        print $_  if ($_ =~ $re);
      }
      close($FILE);
    }
  },

} );

cmpthese $bench;

1;

我也不明白为什么“
while()
”比“
while(my$line=$z->getline())
”慢……

在典型的桌面硬件上,zcat几乎肯定会对非平凡数据进行I/O限制(您的示例文件非常平凡,它们肯定会被缓冲),在这种情况下,不会有任何代码级优化对您有效。生成一个外部gzip对我来说似乎很完美。

上次我尝试它时,生成一个外部的
gunzip
比使用Perl模块要快得多(就像你的基准测试显示的那样)。我怀疑这是绑定文件句柄所涉及的所有方法调用

我希望
$z->getline
慢,原因类似。要弄清楚第一个需要翻译成第二个,需要更多的魔法

我也不明白为什么
while()
while(我的$line=$z->getline())慢

因为
$z
是一个自绑定对象,绑定对象的速度非常慢,而且
使用绑定对象接口调用
getline()
,而不是直接调用该方法


您也可以尝试,但我怀疑它不会比其他模块快多少。

我按照runrig的建议更新了基准测试

我的最新基准:

#!/usr/bin/perl

use strict;
use warnings;
use Benchmark qw(cmpthese timethese);
use IO::Uncompress::Gunzip qw(gunzip);

my $re = qr/test/;

my $bench = timethese($ARGV[1], {

  zcat => sub {
    if (defined open(my $FILE, "-|", "zcat " . $ARGV[0]))
    {
      while (<$FILE>)
      {
        print $_  if ($_ =~ $re);
      }
      close($FILE);
    }
  },

  io_gunzip => sub {
    my $z = new IO::Uncompress::Gunzip $ARGV[0];
    while (<$z>)
    {
      print $_  if ($_ =~ $re);
    }
  },

  io_gunzip_getline => sub {
    my $z = new IO::Uncompress::Gunzip $ARGV[0];
    while (my $line = $z->getline())
    {
      print $line if ($line =~ $re);
    }
  },

} );

cmpthese $bench;

1;
#!/usr/bin/perl

use strict;
use warnings;
use Benchmark qw(cmpthese timethese);
use IO::Uncompress::Gunzip qw(gunzip);
use PerlIO::gzip;

my $re = qr/test/;

my $bench = timethese($ARGV[1], {

  zcat => sub {
    if (defined open(my $FILE, "-|", "zcat " . $ARGV[0]))
    {
      while (<$FILE>)
      {
        print $_  if ($_ =~ $re);
      }
      close($FILE);
    }
  },

  io_gunzip => sub {
    my $z = new IO::Uncompress::Gunzip $ARGV[0];
    while (<$z>)
    {
      print $_  if ($_ =~ $re);
    }
  },

  io_gunzip_getline => sub {
    my $z = new IO::Uncompress::Gunzip $ARGV[0];
    while (my $line = $z->getline())
    {
      print $line if ($line =~ $re);
    }
  },

  perlio_gzip => sub {
    if (defined open(my $FILE, "<:gzip", $ARGV[0]))
    {
      while (<$FILE>)
      {
        print $_  if ($_ =~ $re);
      }
      close($FILE);
    }
  },

} );

cmpthese $bench;

1;

是最快的解决方案

在cpan.org上查看-可能有一个模块可以做到这一点。@Paul:like IO::Uncompress::Gunzip?我在手机上写了这条评论,所以我没有办法查找并写出真实的答案,但这听起来确实像是一个可能的候选人。你的问题远没有你的标题所显示的那么笼统。您希望保持原始文件未压缩,并对整个未压缩内容进行操作(在本例中是使用正则表达式)。这是一个比“使用Perl压缩文件的最佳方式是什么?”更为具体的问题。+1用于回答我的第二个问题,但我对第一个问题的答案更感兴趣…:)实际上,PerlIO::gzip似乎是最快的一个。。。真快!我会很快用我的新板凳更新我的问题!不幸的是,PerlIO::gzip没有打包在Debian中…:(这忽略了这样一个事实,即分叉zcat可以(并且将,如果可用)使用第二个CPU内核,然后导致较低的时钟计时。Benchmark.pm完全忽略实际的时钟计时,并根据CPU时间(包括child)的总和计算s/iter和速率(可能并行运行)因此,即使zcat在有2个内核的情况下完成得更快,它也会声称perlio_gzip比m更快-(…而且,解压600K的速度可能太快,初始开销太重,请尝试更大的文件。这篇文章现在已经有将近7年的历史了。PerlIO::gzip最近被打包在Debian中:$sudo apt get install libperlio gzip perlThen,它仍然不在RHEL中(尽管您可以从Fedora获得它)。:)如果你有多个核心,你就可以有效地将它们之间的工作分开。如果你使用一个库,那么它们都在同一个核心上。