访问 Match.group() 的成本是多少?
How expensive is accessing Match.group()?
试图优化一些重用匹配组的代码,我想知道访问 Match.group()
是否很昂贵。我试图挖掘 re.py 的源代码,但代码有点神秘。
一些测试似乎表明将 Match.group()
的输出存储在变量中可能会更好,但我想了解调用 Match.group()
时到底发生了什么,如果还有另一种内部方式可以直接访问组的内容。
一些示例代码来说明潜在用途:
import re
m = re.search('X+', f'__{"X"*10000}__')
# do something
# m.group()
# do something else
# m.group()
时间
直接访问:
%%timeit
len(m.group())
220 ns ± 1.31 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
中间变量:
X = m.group()
%%timeit
len(X)
# 51 ns ± 0.172 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
参考文献:
current re.py code (python 3.10)
current sre_compile.py code (python 3.10)
消除属性访问的影响(变化不大)
G = m.group
%%timeit
len(G())
230 ns ± 1.12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
匹配对象包含对您搜索的原始字符串的引用,以及每个组开始和结束的索引,包括组 0,整个匹配字符串。每次调用 group()
都会将原始字符串切片以创建一个新字符串 return.
将 return 值保存到一个变量中,避免了每次都必须对字符串进行切片的时间和内存成本。 (它也避免了重复方法调用的开销。)
您可以看到 group()
不仅仅是 return 缓存的字符串,因为 return 值并不总是同一个对象:
>>> import re
>>> x = re.search(r'sd', 'asdf')
>>> x.group() is x.group()
False
如果想看group()
的实现,在Python源码Modules/_sre.c
中的match_group
。
.group
可用于访问整个匹配项(当未提供参数时)或特定组(当给出参数时),例如
import re
m = re.match('(X)X+','XXXXX')
print(m.group(1)) # output X
请注意,re.Match
个实例有 .string
,您可以访问完整的字符串,即
import re
m = re.match('(X)X+','XXXXX')
print(m.string) # output XXXXX
试图优化一些重用匹配组的代码,我想知道访问 Match.group()
是否很昂贵。我试图挖掘 re.py 的源代码,但代码有点神秘。
一些测试似乎表明将 Match.group()
的输出存储在变量中可能会更好,但我想了解调用 Match.group()
时到底发生了什么,如果还有另一种内部方式可以直接访问组的内容。
一些示例代码来说明潜在用途:
import re
m = re.search('X+', f'__{"X"*10000}__')
# do something
# m.group()
# do something else
# m.group()
时间
直接访问:
%%timeit
len(m.group())
220 ns ± 1.31 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
中间变量:
X = m.group()
%%timeit
len(X)
# 51 ns ± 0.172 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
参考文献:
current re.py code (python 3.10)
current sre_compile.py code (python 3.10)
消除属性访问的影响(变化不大)
G = m.group
%%timeit
len(G())
230 ns ± 1.12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
匹配对象包含对您搜索的原始字符串的引用,以及每个组开始和结束的索引,包括组 0,整个匹配字符串。每次调用 group()
都会将原始字符串切片以创建一个新字符串 return.
将 return 值保存到一个变量中,避免了每次都必须对字符串进行切片的时间和内存成本。 (它也避免了重复方法调用的开销。)
您可以看到 group()
不仅仅是 return 缓存的字符串,因为 return 值并不总是同一个对象:
>>> import re
>>> x = re.search(r'sd', 'asdf')
>>> x.group() is x.group()
False
如果想看group()
的实现,在Python源码Modules/_sre.c
中的match_group
。
.group
可用于访问整个匹配项(当未提供参数时)或特定组(当给出参数时),例如
import re
m = re.match('(X)X+','XXXXX')
print(m.group(1)) # output X
请注意,re.Match
个实例有 .string
,您可以访问完整的字符串,即
import re
m = re.match('(X)X+','XXXXX')
print(m.string) # output XXXXX