从perl 5.8(32bit)升级到5.16(64bit) - 正则表达式性能上升

时间:2013-07-23 01:29:17

标签: regex windows performance perl activestate

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

我们注意到性能受到影响,而我们的解析循环需要大约2.5秒,现在大约需要5秒。任何人都可以给我一个暗示会导致变化的提示吗?我期待性能提升,因为我的理解是引擎有了很大的改进,任何关于我应该做的事情的文档都会非常感激。

2 个答案:

答案 0 :(得分:7)

是的,在v8之后,正则表达式引擎得到了很大的改进。在第10版中,我们看到了:

  • 模式递归
  • 命名捕获
  • 占有量词
  • 回溯控制动词,例如(*FAIL)(*SKIP)
  • \K运算符
  • ......还有一些

此外,更多内部设备可以识别Unicode。

在v12中,清除了Unicode支持。现在,正则表达式中的\p\X运算符得到了极大的增强。

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

  • 正则表达式现在可以携带charclass修饰符,如/u/d/l/a/aa
  • 实施了/r的非破坏性嫌疑。
  • RE引擎现在是可重入的,因此嵌入代码可以使用正则表达式。
  • \p已清理
  • 当需要切换到unicode语义时,正则表达式编译速度更快。

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

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

显然,并非所有这些功能都需要付出代价,但尤其是Unicode感知会使内部组件更复杂,速度更慢。

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

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

基本上,您必须比较整个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

这些示例以及unpackindex可能不适用于您的代码,但如果他们这样做,您应该对它们进行基准测试,看看它是否有助于提高性能。