我正在运行一系列针对数据块的正则表达式。我们最近从Activestate perl 5.8 32bit(我知道......非常老!)升级到perl 5.16 64bit。所有硬件保持不变(窗口)。
我们注意到性能受到影响,而我们的解析循环需要大约2.5秒,现在大约需要5秒。任何人都可以给我一个暗示会导致变化的提示吗?我期待性能提升,因为我的理解是引擎有了很大的改进,任何关于我应该做的事情的文档都会非常感激。
答案 0 :(得分:7)
是的,在v8之后,正则表达式引擎得到了很大的改进。在第10版中,我们看到了:
(*FAIL)
或(*SKIP)
。\K
运算符此外,更多内部设备可以识别Unicode。
在v12中,清除了Unicode支持。现在,正则表达式中的\p
和\X
运算符得到了极大的增强。
在第14版中,Unicode支持被提升到6.0。 \N
运算符的字符名得到了改进(另请参阅charnames
编译指示)。新的字符模型可以将任何无符号整数视为代码点。在正则表达式引擎中,
/u
,/d
,/l
,/a
,/aa
。/r
的非破坏性嫌疑。\p
已清理在v16中,perl几乎支持Unicode 6.1。在正则表达式引擎中,
\p
charclasses的效率提高了。显然,并非所有这些功能都需要付出代价,但尤其是Unicode感知会使内部组件更复杂,速度更慢。
你也不能放弃一只手,并说明脚本的执行时间从perl5 v8 x86加倍到perl5 v16 x64;变量太多了:
基本上,您必须比较整个perl -V
输出。
如果你使用正则表达式达到性能上限,它们可能是进行大量解析的错误工具。至少,您可以使用较新的功能来优化正则表达式,以消除一些回溯。
如果您的解析代码描述了(大致)无上下文语言(即您不使用(?{...})
,(?=...)
或相关的正则表达式功能),解析意味着执行类似生成树的操作,那么Marpa::R2可能会大大加快速度。
答案 1 :(得分:0)
如果您正在寻找更好的性能,您可能还需要确保正则表达式是您想要的。您没有指定系统使用的正则表达式,但通常可以使用内置函数替换正则表达式。
示例:
if (lc($name) eq 'bob') { $bob_count++ } #Faster
if ($name =~ /^bob$/i) { $bob_count++ } #Slower
my $sentiment = "I don't like beans.";
substr($sentiment, 13, 5) = 'broccoli'; #Faster
$sentiment = "I don't like beans.";
$sentiment =~ s/beans/broccoli/; #Slower
这些示例以及unpack
和index
可能不适用于您的代码,但如果他们这样做,您应该对它们进行基准测试,看看它是否有助于提高性能。