读取命令性能

  • 本文关键字:性能 命令 读取 perl
  • 更新时间 :
  • 英文 :


我的目标是对流程中产生的数据(基于行)进行一些正则表达式和处理。由于我在perl中已经有了很多工具,所以我决定使用perl来解决我的问题。

比方说一个输出大文件的过程,例如:

cat LARGEFILE.txt | grep"字符串"

显然,我想调用的进程不是"cat",而是输出一堆行(通常是100GB的数据)的进程。

我怀疑我的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示例慢,但我没想到会有那么大的差异。

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

附言:我在Linux盒子上使用perl v.10.1

您可以试用sysread:

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

use warnings;
use strict;
use Data::Dumper;
my $filename = "test.txt";
die "filename not foundn" unless -f $filename;
my $size = -s $filename;
my $total_read = 0;
open my $fh, "<", $filename or die "can't open $filenamen";
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: $sizen";
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";
}

最新更新