“因此,更新后的问题是,为什么现在搜索出表现是否匹配?”
在一个字符串使用,而不是一个正则表达式这种特殊的情况下,确实re.search
比re.match
默认CPython的实现(我还没有在Python的其他化身测试这一点)稍快。
>>> print timeit.timeit(stmt="r.match(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('hello')",
... number = 10000000)
3.29107403755
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('hello')",
... number = 10000000)
2.39184308052
展望C code behind those modules,它出现在搜索代码有一个内置的优化to quickly match patterns prefixed with a string lateral。在上面的示例中,整个模式是一个没有正则表达式模式的文字字符串,所以这个优化的例程用于匹配整个模式。
通知一旦我们介绍的正则表达式的符号和,作为文字串前缀变短的性能如何降低:
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('hell.')",
... number = 10000000)
3.20765399933
>>>
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('hel.o')",
... number = 10000000)
3.31512498856
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('he.lo')",
... number = 10000000)
3.31983995438
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('h.llo')",
... number = 10000000)
3.39261603355
对于包含正则表达式模式的图案的部分,SRE_MATCH被用于确定匹配。这与re.match
背后的代码基本相同。
如果模式以正则表达式模式而非文字字符串开头,请注意结果如何接近(re.match
稍快)。
>>> print timeit.timeit(stmt="r.match(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('.ello')",
... number = 10000000)
3.22782492638
>>> print timeit.timeit(stmt="r.search(s)",
... setup="import re; s = 'helloab'*100000; r = re.compile('.ello')",
... number = 10000000)
3.31773591042
换句话说,忽略这一事实search
和match
具有不同的目的,re.search
比re.match
更快仅当模式是文字串。
当然,如果您使用的是文字字符串,您可能更愿意使用字符串操作。
>>> # Detecting exact matches
>>> print timeit.timeit(stmt="s == r",
... setup="s = 'helloab'*100000; r = 'hello'",
... number = 10000000)
0.339027881622
>>> # Determine if string contains another string
>>> print timeit.timeit(stmt="s in r",
... setup="s = 'helloab'*100000; r = 'hello'",
... number = 10000000)
0.479326963425
>>> # detecting prefix
>>> print timeit.timeit(stmt="s.startswith(r)",
... setup="s = 'helloab'*100000; r = 'hello'",
... number = 10000000)
1.49393510818
>>> print timeit.timeit(stmt="s[:len(r)] == r",
... setup="s = 'helloab'*100000; r = 'hello'",
... number = 10000000)
1.21005606651
你真的应该在'setup'参数中为'timeit'构建测试字符串和正则表达式对象,这样你只能测量匹配/搜索本身。并且做10次以上的迭代。 – interjay
@interjay:增加到10000。试过'号码= 100000',但在我的上网本上花费了太多时间。 – RanRag
...但你没有做我说的其他事情,所以你没有测量任何重要的问题(大部分时间都花在构建字符串上)。 – interjay