Regex 从perl 5.8(32位)升级到5.16(64位)-正则表达式性能达到要求

Regex 从perl 5.8(32位)升级到5.16(64位)-正则表达式性能达到要求,regex,windows,performance,perl,activestate,Regex,Windows,Performance,Perl,Activestate,我正在对数据块运行一系列正则表达式。我们最近从Activestate perl 5.8 32位(我知道…非常旧!)升级到perl 5.16 64位。所有硬件都保持不变(windows) 我们注意到一个性能问题,与以前一样,解析循环大约需要2.5秒,现在大约需要5秒。有谁能给我一个提示,是什么导致了这种变化?我期待性能的提高,因为我的理解是引擎已经有了很大的改进,任何关于我应该做什么的文档都将不胜感激。是的,regex引擎在v8之后有了很大的改进。仅在v10中,我们看到: 模式递归 命名捕获 所

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


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

是的,regex引擎在v8之后有了很大的改进。仅在v10中,我们看到:

  • 模式递归
  • 命名捕获
  • 所有格量词
  • 回溯控制动词,如
    (*FAIL)
    (*SKIP)
  • \K
    运算符
  • ……还有更多
此外,还使更多的内部构件具有Unicode意识

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

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

  • 正则表达式现在可以携带charclass修饰符,如
    /u
    /d
    /l
    /a
    /aa
  • 采用
    /r
    进行无损替换
  • RE引擎现在是可重入的,因此嵌入式代码可以使用正则表达式
  • \p
    已清除
  • 当需要切换到unicode语义时,正则表达式编译速度更快
在v16中,perl几乎支持Unicode 6.1。在正则表达式引擎中

  • \p
    类的效率提高
  • 修复了各种正则表达式错误(通常涉及不区分大小写的匹配)
显然,并非所有这些特性都是有代价的,但特别是Unicode意识使得内部结构更加复杂,速度也更慢

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

  • 两个PERL是否都使用相同的标志编译?
    • 这两个线程都是线程化的(禁用线程支持会加快速度)
    • 你的整数有多大?64位还是32位
    • 选择了哪些编译器优化
  • 您以前的Perl是否应用了一些特定于发行版的修补程序
基本上,您必须比较整个
perl-V
输出


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


如果您的解析代码描述了一种(大致)上下文无关的语言(即,您不使用
(?{…})
(?=…)
或相关的正则表达式功能),那么解析意味着执行类似生成树的操作,然后可能会大大加快速度。

如果您希望获得更好的性能,您可能还需要确保正则表达式是您想要的。您没有指定系统使用的正则表达式类型,但通常可以用内置函数替换正则表达式

示例:

if (lc($name) eq 'bob') { $bob_count++ }  #Faster
if ($name =~ /^bob$/i)  { $bob_count++ }  #Slower 


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

时间只读取数据,而不进行任何处理,看看与此有多大的区别我在“更新”中看到了一些关于regex的问题/注释由于与旧版本的Perl(或其他)相比更正确地实现unicode,Perl版本的速度较慢。我不知道这有多少道理,但也许你可以研究一下。我知道问题是关于perl升级后的性能下降。你的回答没有提到版本之间可能发生的任何变化。相反,您提供的一般优化提示与问题几乎没有关联。(除非在执行之前知道
$touction
的内容,否则您的替换示例甚至不是等效的。您可能是指
如果(0)我读了一些字里行间的内容,了解到无论是什么原因导致减速,提问者可能仍然会有性能问题。我的回答指出,有时性能问题可以通过消除正则表达式来解决。这与问题直接相关。我试着说明这些示例uld必须在讨论中的特定代码上进行测试。因此,是的,他的代码不太可能包含包含字符串“我不喜欢beans”的变量。我认为这太明显了,不值得一提。谢谢amon。这是我们可以检查的一些项目的一个很好的总结,我非常感谢您花时间写出来!
my $sentiment = "I don't like beans.";
substr($sentiment, 13, 5) = 'broccoli';   #Faster
$sentiment = "I don't like beans.";
$sentiment =~ s/beans/broccoli/;          #Slower