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
}
答案 0 :(得分:3)
根据请求发表评论作为答案:
您可以像这样存储子程序ref:
perl -lwe 'my $x = eval(q( sub { my $foo = shift; $foo*2; } )); print $x->(12);'
这会打印24
。您可以重新使用代码而无需重新编译它。