Python Regex比预期慢

时间:2015-07-01 14:43:24

标签: python regex performance

我读了一篇关于如何避免创建慢速正则表达式的酷article。一般来说,它看起来更长,更明确,正则表达式更快完成。贪婪的正则表达式可以指数速度慢。

我想我会通过测量用较不复杂/贪婪的语句完成更复杂/显式语句所花费的时间来测试它。在大多数情况下,一切似乎都是正确的,但我有一个贪婪的声明,速度较慢。以下是两个例子:

import re
from timeit import timeit

# This works as expected, the explicit is faster than the greedy.
# http_x_real_ip explicit 
print(timeit(setup="import re", stmt='''r = re.search(r'(\d{1,3}\.\d{1,3}.\d{1,3}.\d{1,3})', '192.168.1.1 999.999.999.999')''', number=1000000))
1.159849308001867

# http_x_real_ip greedy
print(timeit(setup="import re", stmt='''r = re.search(r'((?:\d{1,3}\.){3}\d{1,3})', '192.168.1.1 999.999.999.999')''', number=1000000))
1.7421739230003368

# This does not work as expected, greedy is faster.
# time_local explicit
print(timeit(setup="import re", stmt='''r = re.search(r'(\d{1,2}/\w{3}/[2][0]\d{2}:\d{2}:\d{2}:\d{2}\s[+][0]{4})', "[23/Jun/2015:11:10:57 +0000]")''', number=1000000))
1.248802040994633

# time_local greedy
print(timeit(setup="import re", stmt='''r = re.search(r'\[(.*)\]', "[23/Jun/2015:11:10:57 +0000]")''', number=1000000))
1.0256699790043058

local_time explict正则表达式写得不好吗?

2 个答案:

答案 0 :(得分:2)

正则表达式越需要回溯,它就越慢。

这可能不适用于非常小的输入数据。但是,谁会关心小数据的表现呢? :d

本文详细介绍了此主题:

此问题也有一些有趣的贡献:

答案 1 :(得分:2)

您也没有使用Python正则表达式的re.compile功能,这意味着您的搜索时间还包括re模块在每次迭代时编译正则表达式的时间。

>>> print(timeit(setup="import re", stmt='''r = re.search(r'(\d{1,3}\.\d{1,3}.\d{1,3}.\d{1,3})', '192.168.1.1 999.999.999.999')''', number=1000000))
0.73820400238
>>> print(timeit(setup="import re; regex = re.compile(r'(\d{1,3}\.\d{1,3}.\d{1,3}.\d{1,3})')", stmt='''r = regex.search('192.168.1.1 999.999.999.999')''', number=1000000))
0.271140813828
>>> print(timeit(setup="import re; regex = re.compile(r'((?:\d{1,3}\.){3}\d{1,3})')", stmt='''r = regex.search('192.168.1.1 999.999.999.999')''', number=1000000))
0.31952214241
>>> print(timeit(setup="import re; regex = re.compile(r'(\d{1,2}/\w{3}/[2][0]\d{2}:\d{2}:\d{2}:\d{2}\s[+][0]{4})')", stmt='''r = regex.search("[23/Jun/2015:11:10:57 +0000]")''', number=1000000))
0.371844053268
>>> 

这里贪婪和非贪婪的正则表达式之间的区别实际上比预编译时更接近预期。其余的解释是回溯。

如果您为大量迭代预编译正则表达式,我们可以看到您的测试速度提高了近3倍。

这个答案是为了补充@ mescalinum的答案,但是对于大量的正则表达式,你应该提前编译正则表达式以进行公平的比较。

相关问题