Speed up multiline regexes anchored by `^`.
未关闭
还没有人认领这个 Issue。
extension-modules
performance
topic-regex
type-feature
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 35.9k
- PR 合并指标
- PR 指标待抓取
描述
Feature or enhancement
Proposal:
I noticed that for regexes of the form
regex = re.compile("^foo", re.MULTILINE)
regex.search(...)
there's a character by character loop calling SRE(match) every iteration. That's significantly slower than the regex
regex = re.compile("foo...")
regex.search(...)
which does a special prefix scan for "foo" without having to call SRE(match) on each character:
I would expect ^foo and foo to have more or less identical performance. A simple patch like this fixes that.
diff --git a/Modules/_sre/sre_lib.h b/Modules/_sre/sre_lib.h
index df377905bfa..70de4cccefd 100644
--- a/Modules/_sre/sre_lib.h
+++ b/Modules/_sre/sre_lib.h
@@ -1855,6 +1855,18 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
return 0;
}
while (status == 0 && ptr < end) {
+ if (pattern[0] == SRE_OP_AT &&
+ pattern[1] == SRE_AT_BEGINNING_LINE &&
+ (void*) ptr > state->beginning &&
+ !SRE_IS_LINEBREAK((int) ptr[-1]))
+ {
+ /* fast-forward to the next newline character */
+ while (ptr < end && !SRE_IS_LINEBREAK((int) *ptr)) {
+ ptr++;
+ }
+ if (ptr >= end) {
+ return 0;
+ }
+ }
ptr++;
RESET_CAPTURE_GROUP();
TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response
Linked PRs
- gh-148778
- gh-152339
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
先查看链接的 PR,然后阅读 Modules/_sre/sre_lib.h 中的 SRE 搜索循环,尤其是其中引用的前缀扫描代码。重现多行 ^foo 搜索和非锚定的 foo 搜索,并比较它们的性能。在不改变正则表达式行为的情况下,如果锚定情况的速度有可测量的接近,即视为完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- performance
- Issue 类型
- 功能
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 35/100