优化Perl外部命令

优化Perl外部命令,perl,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+\

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

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
}

为什么不能简单地运行程序并将结果通过管道传输到perl脚本

./program $arg $arg1 | myscript
实际上,您可能完全可以摆脱perl:

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

为什么不能简单地运行程序并将结果通过管道传输到perl脚本

./program $arg $arg1 | myscript
实际上,您可能完全可以摆脱perl:

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

我可以看到一些情况,例如,没有立即将结果加载到文件中,但我怀疑您将获得的主要性能优势可能是使用不同的正则表达式。为此,您对程序的数据输出格式有更好的了解吗

下面是一些可能运行得更快的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;
}
请注意以下几点:

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

我可以看到一些情况,例如,没有立即将结果加载到文件中,但我怀疑您将获得的主要性能优势可能是使用不同的正则表达式。为此,您对程序的数据输出格式有更好的了解吗

下面是一些可能运行得更快的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;
}
请注意以下几点:

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

是的,首先:将程序输出重定向到文件,然后再读取是愚蠢且昂贵的。为什么不呢

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

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

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

my @result = `program $arg $arg1`;
foreach(@result) {...
第二件事是可以并行化外部foreach。perldoc线程,线程::共享。

您有程序吗?如果没有评测,您就不知道大部分时间是花在外部程序上还是花在您的程序上

分析是优化中的一个重要步骤,如果没有它,您基本上是在猜测哪里可以提高速度。分析将显示哪些步骤占用的时间最多

也就是说,您可以使用线程并行化外部程序调用。您还可以通过不同的正则表达式获得一些优化,但是没有真正的方法来判断不首先分析您将获得多少优化。

您有程序吗?如果没有评测,您就不知道大部分时间是花在外部程序上还是花在您的程序上

分析是优化中的一个重要步骤,如果没有它,您基本上是在猜测哪里可以提高速度。分析将显示哪些步骤占用的时间最多


也就是说,您可以使用线程并行化外部程序调用。您也可以通过不同的正则表达式获得一些优化,但是没有真正的方法来判断不先进行分析会获得多少好处。

我也会这样做。在Unix上。也许他在Windows上,安装的只是Perl,他不想安装Cygwin。另一个问题是,这显然是一个更大程序的片段,请参见@data数组。我真的很想写一个bash示例来实现这个循环,但是谁知道他在perl中做了什么呢。@Mike:第一个选项会解决更大的程序问题。我想我们应该问问有多慢即使它是更大程序的一部分,my@lines=program$arg$arg1 | grep。。。我仍然会省去中间人写文件和读文件的麻烦。我也会这样做。在Unix上。也许他在Windows上,安装的只是Perl,他不想安装Cygwin。另一个问题是,这显然是一个更大程序的片段,请参见@data数组。我真的很想写一个bash示例来实现这个循环,但是谁知道他在perl中做了什么呢。@Mike:第一个选项会解决更大的程序问题。我想我们应该问问h

哎呀,太慢了即使它是更大程序的一部分,my@lines=program$arg$arg1 | grep。。。仍然会省去中间人必须写出来并读回文件。-1因为他说结果是一个非常大的文件。将它读入Perl列表可能会使他的RAM溢出。他说$arg1是一个非常大的文件。他没有说程序输出非常大,这就是为什么perl允许您在open中使用pipe:您提供的程序甚至不像您想象的那样工作。请删除此答案。@Brad Gilbert nnaah。。。我会保持原样。-1因为他说结果是一个非常大的文件。将它读入Perl列表可能会使他的RAM溢出。他说$arg1是一个非常大的文件。他没有说程序输出非常大,这就是为什么perl允许您在open中使用pipe:您提供的程序甚至不像您想象的那样工作。请删除此答案。@Brad Gilbert nnaah。。。我就不说了。你觉得哪一部分太慢了?你没有告诉我们最重要的事情:@data和$result有多大?这些参数对程序的速度影响最大。如果两者都不是特别大,那么解决方案就在于另一个程序。你能以任何方式修改它吗?最根本的改进是它接受多个$arg值,只处理一次非常大的文件,并生成一批输出。您觉得哪部分太慢了?您没有告诉我们最重要的事情:@data和$result有多大?这些参数对程序的速度影响最大。如果两者都不是特别大,那么解决方案就在于另一个程序。你能以任何方式修改它吗?最根本的改进是它接受多个$arg值,只处理一次非常大的文件,并生成一批输出。我认为您不理解线程建议。如果他将foreach my$arg@data循环转换为一组线程,那么他可以并行运行程序两次或更多次,从而潜在地加快了程序的运行速度。在open函数中放置管道并不能做到这一点。据我所知,这将是难以置信的发生。我想你没有理解线程的建议。如果他将foreach my$arg@data循环转换为一组线程,那么他可以并行运行程序两次或更多次,从而潜在地加快了程序的运行速度。在open函数中放置管道并不能做到这一点。据我所知,这将是难以置信的发生。