我有一个应用程序代码,可以从配置中动态生成正则表达式以进行一些解析.当两个变化的定时性能时,正被捕获的OR正则表达式的每个部分的正则表达式变化明显慢于正常正则表达式.原因是regex模块内部某些操作的开销.
>>> import timeit
>>> setup = '''
... import re
... '''
#no capture group
>>> print(timeit.timeit("re.search(r'hello|bye|ola|cheers','some say hello,some say bye, or ola or cheers!')", setup=setup))
0.922958850861
#with capture group
>>> print(timeit.timeit("re.search(r'(hello)|(bye)|(ola)|(cheers)','some say hello,some say bye, or ola or cheers!')", setup=setup))
1.44321084023
#no capture group
>>> print(timeit.timeit("re.search(r'hello|bye|ola|cheers','some say hello,some say bye, or ola or cheers!')", setup=setup))
0.913202047348
# capture group
>>> print(timeit.timeit("re.search(r'(hello)|(bye)|(ola)|(cheers)','some say hello,some say bye, or ola or cheers!')", setup=setup))
1.41544604301
Run Code Online (Sandbox Code Playgroud)
问题:使用捕获组时,导致性能大幅下降的原因是什么?
Fed*_*zza 19
原因很简单,使用捕获组指示Engine将内容保存在内存中,而使用非捕获组则表示引擎不保存任何内容.请考虑您告诉引擎执行更多操作.
例如,使用此正则表达式(hello|bye|ola|cheers)或(hello)|(bye)|(ola)|(cheers)将比使用原子组或非捕获原子组的影响大得多(?:hello|bye|ola|cheers).
使用正则表达式时,您知道是否要捕获或不捕获内容,如上所述.如果你想捕获任何这些单词,你将失去性能,但如果你不需要捕获内容,那么你可以通过改进它来保存性能,就像使用非捕获组一样
我知道你标记了python,但是已经准备好了javascript的在线基准测试,以显示捕获和非捕获组如何影响js正则表达式引擎.
https://jsperf.com/capturing-groups-vs-non-capturing-groups
Wik*_*żew 11
您的模式仅在捕获组中有所不同.在正则表达式模式中定义捕获组并使用模式时re.search,结果将是一个 MatchObject实例.每个匹配对象将包含与模式中的捕获组一样多的组,即使它们是空的.这是re内部的开销:添加(列表)组(内存分配等).请注意,组还包含诸如匹配的文本的起始和结束索引等详细信息(请参阅MatchObject参考资料).