Regex 从perl 5.8(32位)升级到5.16(64位)-正则表达式性能达到要求
我正在对数据块运行一系列正则表达式。我们最近从Activestate perl 5.8 32位(我知道…非常旧!)升级到perl 5.16 64位。所有硬件都保持不变(windows)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中,我们看到: 模式递归 命名捕获 所
我们注意到一个性能问题,与以前一样,解析循环大约需要2.5秒,现在大约需要5秒。有谁能给我一个提示,是什么导致了这种变化?我期待性能的提高,因为我的理解是引擎已经有了很大的改进,任何关于我应该做什么的文档都将不胜感激。是的,regex引擎在v8之后有了很大的改进。仅在v10中,我们看到:
- 模式递归
- 命名捕获
- 所有格量词
- 回溯控制动词,如
或(*FAIL)
(*SKIP)
运算符\K
- ……还有更多
\p
和\X
操作符现在得到了极大的增强
在v14中,Unicode支持被提升到6.0。\N
运算符的字符名得到了改进(另请参见Charnames
pragma)。新的字符模型可以将任何无符号整数视为码点。在正则表达式引擎中
- 正则表达式现在可以携带charclass修饰符,如
,/u
,/d
,/l
,/a
/aa
- 采用
进行无损替换/r
- RE引擎现在是可重入的,因此嵌入式代码可以使用正则表达式
已清除\p
- 当需要切换到unicode语义时,正则表达式编译速度更快
类的效率提高\p
- 修复了各种正则表达式错误(通常涉及不区分大小写的匹配)
- 两个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