【发布时间】:2012-11-01 14:19:28
【问题描述】:
以下 Python 代码非常慢:
import re
re.match( '([a]+)+c', 'a' * 30 + 'b' )
如果将 30 替换为更大的常数,情况会变得更糟。
我怀疑由于连续的+ 导致的解析歧义是罪魁祸首,但我在正则表达式解析和匹配方面不是很专家。这是 Python 正则表达式引擎的错误,还是任何合理的实现都会这样做?
我不是 Perl 专家,但下面的返回速度很快
perl -e '$s="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"; print "ok\n" if $s =~ m/([a]+)+c/;'
增加“a”的数量并不会显着改变执行速度。
【问题讨论】:
-
看看catastrophic backtracking。如果引擎没有优化掉两个
+s,这可能会变得非常糟糕,特别是因为在两次重复之间存在捕获组,并且捕获相对昂贵。 -
@m.buettner:是的,而且可能 Perl 的引擎足够聪明,可以将其过滤掉。让它成为答案!
-
下面是如何在 Perl 中对其进行基准测试:
perl -E 'use Benchmark ":hireswallclock"; $s="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"; $t0 = Benchmark->new; say "ok" if $s =~ m/([a]+)+c/; $t1 = Benchmark->new; say timestr(timediff($t0, $t1))' -
这里是 idoene 的 5 秒超时:ideone.com/QwOjSE