从命令性能中读取

时间:2014-04-24 14:54:41

标签: perl

我的目标是对流程中出现的数据(基于行)进行一些正则表达式和一些处理。由于我已经在perl中获得了大量工具,因此我决定使用perl来解决我的问题。

让我们说一个输出大文件的过程,例如:

cat LARGEFILE.txt | grep"一个字符串"

显然我要打电话的过程不是" cat"但输出一堆行(通常是100 GB的数据)的东西。

我怀疑我的perl程序的性能,并开始将代码删除到最低限度。我意识到我的问题可能来自于我在perl中读取命令输出的方式。

这是我的perl脚本:

#!/usr/bin/perl

use strict;

open my $fh, "cat LARGE.txt |";
while (<$fh>) {
        print $_ if $_ =~ qr/REGEX NOT TO BE FOUND/o;
}

我决定将我的程序与一个简单的bash命令进行比较:

cat LARGE.txt | grep "REGEX NOT TO BE FOUND"

结果:

time cat LARGE.txt | grep "REGEX NOT TO BE FOUND"
real    0m0.615s
user    0m0.352s
sys     0m0.873s

time ./test.pl 

real    0m37.339s
user    0m36.621s
sys     0m1.766s

在我的示例中,LARGE.txt文件大约是1.3GB。

我知道perl解决方案可能比cat | grep示例慢,但我没想到会有太大差异。

我的阅读命令输出方式有问题吗?

P.S。我在Linux机器上使用perl v5.10.1

1 个答案:

答案 0 :(得分:1)

你可以试试sysread:

(被盗:http://www.perlmonks.org/?node_id=457046

use warnings;
use strict;
use Data::Dumper;

my $filename = "test.txt";

die "filename not found\n" unless -f $filename;

my $size = -s $filename;
my $total_read = 0;

open my $fh, "<", $filename or die "can't open $filename\n";
binmode($fh);

my $bufsize = 8192; # typical size for i/o buffers
my ( $databuf, $readbuf, $nread );
while (( $nread = sysread( $fh, $readbuf, $bufsize )) > 0 ) {
    $databuf .= $readbuf;
    process_lines_from_buffer(\$databuf);
}
print "initial size: $size\n";

sub process_lines_from_buffer{
    ### to make it efficient do not use a named variable for the buffer
    return undef if ! defined $_[0];
    while (${$_[0]} =~ s!(.*?)\n!!){
        ### do your processing
        process_line(\$1);
    }
}
sub process_line {
    print ${$_[0]}."\n";
}