Python 正则表达式执行时间在第100个模式之后急剧增加

Python 正则表达式执行时间在第100个模式之后急剧增加,python,Python,我从下面的第一个代码片段开始搜索行列表,并将每行中的所有关键字(在单独的列表中标识)转换为小写。对于我大约800行的测试列表,只要我的关键字列表是100项或更少,整个行列表的关键字替换就不到一秒钟。当我将列表扩展到101项或更多项时,处理时间会跳到9秒以上 使用第二个代码段(其中编译了关键字列表的所有模式)将总处理时间降低到1秒以下 有人知道为什么非编译替换搜索的处理时间对每个输入行搜索的项目数如此敏感吗?我很惊讶它在100个关键词之后跳得如此之快 片段#1 片段#2 对于re.compile,

我从下面的第一个代码片段开始搜索行列表,并将每行中的所有关键字(在单独的列表中标识)转换为小写。对于我大约800行的测试列表,只要我的关键字列表是100项或更少,整个行列表的关键字替换就不到一秒钟。当我将列表扩展到101项或更多项时,处理时间会跳到9秒以上

使用第二个代码段(其中编译了关键字列表的所有模式)将总处理时间降低到1秒以下

有人知道为什么非编译替换搜索的处理时间对每个输入行搜索的项目数如此敏感吗?我很惊讶它在100个关键词之后跳得如此之快

片段#1

片段#2

对于re.compile,他说:

请注意传递给的最新模式的编译版本 re.match()、re.search()或re.compile()被缓存,因此 一次只使用几个正则表达式,不必担心 编译正则表达式


我想我们现在知道了缓存的大小。

这是因为Python在内部缓存编译的正则表达式,而内部缓存的大小是100(如第227行所示。此外,您可以在第246-247行中看到,当缓存超过最大大小时,将被清除,而不是使用更高级的缓存失效算法。这本质上意味着循环的每次迭代都会破坏缓存,并导致所有100多个正则表达式重新编译


性能恢复“正常”在您的第二个示例中,因为它不依赖内部缓存保持编译的正则表达式的完整性。

这是由于re模块中编译的正则表达式的内部缓存。如果您在代码中使用了大量的正则表达式,请预编译它们,而不是直接使用re.match或re.search,甚至会出现f阿斯特


内部重新缓存是为了在常见的简单用例中提供方便的速度,而不是高性能。

@grncdr,感谢您指出原因。看到事情按照设计的方式运行总是很好。感谢您指出原因。看到事情按照设计的方式运行总是很好。
for line in lines_in:
    for keyword in keywords:
        rawstring = r'\b' + keyword + r'\b'
        line = re.sub(rawstring, keyword, line, 0, re.IGNORECASE)
for i in range(len(keywords)):
    re_pattern = re.compile(r'\b' + keywords[i] + r'\b', re.IGNORECASE)
    pattern.append(re_pattern)

for line in lines_in:
    for i in range(len(keywords)):
        line = pattern[i].sub(keywords[i], line, 0)