优化Perl外部命令

时间:2010-09-14 18:06:08

标签: perl

有什么方法可以优化以下脚本以更快地运行?

foreach my $arg (@data){ #  
   @score=();
   `program $arg $arg1 > $result`; #!!! $arg1 is a very large file with lots of data!!!
   open(FH,$result);
   while(<FH>){
      chomp;
      if($_ =~ /\d+.+\s+(\d+\.\d+|\d+\.|\.\d+).+/){ #here i'm looking for any number such as: 21.343 or 12 or 0.22 or -3.0
         push(@score, $1);
      }
   }
   close FH;
   @sorted = sort{$a <=> $b} @score; #a sorted score is what i actually want
}

4 个答案:

答案 0 :(得分:5)

我可以看到一些东西(例如没有立即将结果加载到文件中),但我怀疑你将获得的主要性能优势可能来自使用不同的正则表达式。为此,您是否更好地了解程序中的数据输出格式是什么?

以下是一些可能运行得更快的perl示例:

use strict;
foreach my $arg (@data){
  my @score=();
  open(my $fh, "program $arg $arg1 |");
  while (<$fh>) {
    chomp;
    if (/\d+.+\s+((\d+)?\.?\d+)/o) {
      push(@score, $1);
    }
  }
  close($fh);
  my @sorted = sort { $a <=> $b } @score;
}

请注意以下几点:

  1. 我正在使用程序文件处理程序,因此我没有使用临时文件,因此跳过了整个数据传递。
  2. 我将正则表达式更改为使用嵌套组而不是多个选项。
  3. 我使用严格并保留包名(因为上帝的爱在你的perl中使用严格)。
  4. 其他人都说要使用线程。你不需要这样做,因为像在open函数中使用尾随管道(|)一样运行进程会导致perl为你分叉一个进程。然后使用标准的unix管道异步读取程序。

答案 1 :(得分:2)

为什么不能简单地运行程序并将结果传递给perl脚本?

./program $arg $arg1 | myscript

实际上,你可能完全摆脱了perl:

./program $arg $arg1 | grep /\d...whatever.../ | sort

答案 2 :(得分:2)

你有profiled你的计划吗?如果没有分析,您不知道绝大多数时间是花在外部程序还是程序中。

分析是优化中的重要一步,如果没有它,您实际上就是猜测可以在哪些方面进行速度改进。分析将显示哪些步骤花费的时间最多。

也就是说,hlynur said,您可以使用线程并行化外部程序调用。你也可以通过一个不同的正则表达式获得一些优化,但没有真正的方法可以告诉你如果没有首先进行分析你会获得多少。

答案 3 :(得分:-1)

是的,首先:将程序输出重定向到文件,之后读取它是愚蠢的&amp;昂贵。为什么不呢?

my @result = `program $arg $arg1`;
foreach(@result) {...

第二件事是你可以并行化外部 foreach 。 perldoc threads,threads :: shared。