繁体   English   中英

正则表达式执行时间在第100个模式后急剧跳跃

[英]regular expression execution time jumps sharply after 100th pattern

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

使用第二个片段(编译关键字列表的所有模式)会将总处理时间减少到1秒以下。

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

片段#1

for line in lines_in:
    for keyword in keywords:
        rawstring = r'\b' + keyword + r'\b'
        line = re.sub(rawstring, keyword, line, 0, re.IGNORECASE)

片段#2

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)

这是因为Python内部缓存编译正则表达式,而内部缓存的大小为100(可以看出这里上线227此外,您可以在线246-247看出,当缓存获得的在最大尺寸是清除而不是使用更高级的缓存失效算法。这实际上意味着循环的每次迭代都会耗尽缓存并导致重新编译所有100多个正则表达式。

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

这是由于re模块中编译的正则表达式的内部缓存。 如果你在代码中使用了很多正则表达式,那么预编译它们而不是直接使用re.match或re.search,它会更快。

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

re.compile的文档说:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM