2013-07-23 51 views
3

我对数据块运行一系列正则表达式。我们最近从Activestate perl 5.8 32bit(我知道......非常老!)升级到perl 5.16 64bit。所有硬件保持不变(窗口)。从perl 5.8(32bit)升级到5.16(64bit) - 正则表现击中

我们注意到性能问题,在我们的解析循环之前大约需要2.5秒,现在需要大约5秒。任何人都可以给我一个关于什么会导致变化的暗示吗?我期待性能有所提高,因为我的理解是引擎已经有了很大的改进,任何有关我应该做的不同的文档都将不胜感激。

+1

只是在没有做任何处理的情况下读取数据,看看有多大差异 – ysth

+1

我看过一些关于正则表达式的问题/评论,因为更正确地实现unicode,Perl的“新版本”旧版本的Perl(或其他)。不知道那里有多少真相,但也许你可以考虑一下。 – Qtax

回答

7

是的,在v8之后,正则表达式引擎大大改进。独自一人在V10中,我们看到:

  • 模式递归
  • 命名捕获
  • 占有欲量词
  • 原路返回控制动词,如(*FAIL)(*SKIP)
  • \K操作
  • ......以及一些更

此外,越来越多的内部作了Unicode感知的。

在第12版中,Unicode支持已清理完毕。正则表达式中的\p\X运算符现在大大增强了。

在第14版中,Unicode支持被碰撞到了6.0。 \N运营商的姓名得到了改进(另请参阅charnames编译指示)。新的字符模型可以将任何无符号整数视为码点。在正则表达式引擎,

  • 正则表达式现在可以随身携带charclass将修饰符像/u/d/l/a/aa
  • 执行/r的非破坏性索赔。
  • RE引擎现在是可重入的,所以嵌入的代码可以使用正则表达式。
  • \p已清理
  • 当需要切换到unicode语义时,regex编译速度更快。

在v16中,perl几乎支持Unicode 6.1。在正则表达式引擎中,

  • 效率\p特类增加了。
  • 修复了各种正则表达式错误(通常涉及不区分大小写的匹配)。

显然,并非所有这些功能都是以一定的价格出现的,但特别是Unicode意识使得内部结构更复杂,速度更慢。

你也不能放弃一手,说明脚本的执行时间从perl5 v8 x86增加到perl5 v16 x64;有太多的变量:

  • 都是用相同的标志编译的Perl?
    • 都是perls线程perls(禁用线程支持使其更快)
    • 你的整数有多大? 64位或32位?
    • 选择了哪种编译器优化?
  • 您以前的Perl是否有一些特定于发行版的修补程序?

基本上,你必须比较整个perl -V输出。


如果您使用正则表达式达到性能上限,那么它们可能是大量解析的错误工具。至少,您可以使用更新的功能优化正则表达式以消除一些回溯。

如果您解析代码描述了(大约)上下文无关语言(即不使用(?{...})(?=...)或相关的正则表达式的功能),以及解析装置做这样的事情发生在树上,然后Marpa::R2可能会大大加快速度。

+1

谢谢你。这是我们可以研究的一些项目的一个很好的总结,我真的很感激你花时间写出来! – sniperd

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,可能不适用于你的代码,但如果他们这样做,你应该基准,看看他们是否有帮助与表现。

+0

我了解到perl升级后性能下降的问题。你的回答没有提到任何可能在版本之间改变的东西。相反,您提供一般优化提示时几乎没有问题的关联。 (你的替代例子甚至不等价,除非'$ sentiment'的内容在执行前已知,你可能意思是if(0 <=(my $ i = index $ sentiment,“beans”)){substr $ sentiment, $ i,长度“beans”,“brocolli”}') – amon

+0

我在两行之间看了一下,看到无论减速的原因是什么,问题提出者大概仍然会有性能问题。我的答案指出,有时性能问题可以通过消除正则表达式来解决。这与问题直接相关。我试图清楚表明这些例子必须在特定的代码上进行测试。所以,是的,他的代码不太可能包含一个包含字符串“我不喜欢豆”的变量。我认为这太明显,不能提及。 – dms