Perl:加快评估速度

时间:2014-07-23 12:57:24

标签: perl eval

对字符串执行时,

eval速度很慢:首先必须先解析字符串才能执行。

我正在寻找一种缓存解析的方法,这样我就可以将解析后的字符串重新用于另一个eval。下一个eval将是相同的代码,但不会评估相同的值,所以我不能简单地缓存结果。

从我正在寻找的ceval来自https://metacpan.org/pod/Eval::Compile

但我不能使用Eval :: Compile,因为它需要一个C编译器用于平台,而且没有给出用户有一个C编译器。

那么我可以在纯perl中执行与ceval类似的操作吗?

背景

GNU Parallel允许用户提供将在每个参数上进行eval的perl表达式。目前,perl表达式由用户给出为字符串,并为每个参数提供eval。每个参数的perl表达式保持不变。因此,重新编译表达式是一种浪费,因为重新编译不会改变任何内容。

代码分析显示eval是瓶颈之一。

示例

用户输入:$_ .= "foo" and s/a/b/g

用户的脚本存储在$usereval1$usereval2

用户提供存储在@arguments中的10000个随机参数(字符串)。

sub replace {
  my ($script,$arg) = @_;
   local $_;
   $_ = $arg;
   # This is where I would like to cache the parsed $script.
   eval $script;
   return $_;
}

for my $arg (@arguments) {
   # loads of indirect code (in the order of 1000 lines) that call subs calling subs calling subs that eventually does:
   $replaced1 = replace($usereval1,$arg);
   $replaced2 = replace($usereval2,$arg);
   # yet more code that does stuff with $replaced1 $replaced2
}

1 个答案:

答案 0 :(得分:3)

根据请求发表评论作为答案:

您可以像这样存储子程序ref:

perl -lwe 'my $x = eval(q( sub { my $foo = shift; $foo*2; } )); print $x->(12);' 

这会打印24。您可以重新使用代码而无需重新编译它。