3

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

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

4

2 回答 2

7

是的,正则表达式引擎在 v8 之后有了很大的改进。单独在 v10 中,我们看到:

  • 模式递归
  • 命名捕获
  • 所有格量词
  • 回溯控制动词,如(*FAIL)or (*SKIP)
  • 运营\K
  • ……还有更多

此外,更多的内部实现了 Unicode 感知。

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

在 v14 中,Unicode 支持被提升到 6.0。运算符的字符\N名得到了改进(另见charnamespragma)。新的字符模型可以将任何无符号整数视为代码点。在正则表达式引擎中,

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

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

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

显然,并非所有这些功能都是有代价的,但尤其是 Unicode 感知使内部更复杂、更慢。

您也不能放弃并声明脚本的执行时间从 perl5 v8 x86 到 perl5 v16 x64 增加了一倍;变量太多:

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

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


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

如果您的解析代码描述了(大致)上下文无关语言(即您不使用(?{...})(?=...)相关的正则表达式功能),并且解析意味着执行诸如生成树之类的操作,那么Marpa::R2可能会大大加快速度。

于 2013-07-23T10:56:00.407 回答
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可能不适用于您的代码,但如果适用,您应该对它们进行基准测试,看看它是否有助于提高性能。

于 2013-07-23T23:31:56.637 回答