csv.Sniffer.sniff() takes quadratic time on long runs of spaces
维护者通常 1 天内回复
@serhiy-storchaka 已经在做这个了。
开始于 2026年10月26日。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 35/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- python
- 领域
- performance
调研方向
Read Lib/csv.py and inspect the regex search in Sniffer._split_dormant() described in the issue. Reproduce the slowdown with the supplied timing sample, then check that the proposed lookbehind preserves matching results while avoiding repeated attempts within a space run. Done means the long-run timings no longer grow quadratically and the existing csv tests pass.
由索引模型根据 Issue 内容生成。
描述
Bug report
Bug description:
On main, csv.Sniffer().sniff() takes quadratic time when the sample contains a quote character and a long run of spaces that is not followed by one:
import csv, time
for n in (8000, 16000, 32000, 64000):
sample = 'a' + ' ' * n + 'x"\n'
t = time.perf_counter()
try:
csv.Sniffer().sniff(sample)
except csv.Error:
pass
print(n, round(time.perf_counter() - t, 4))
Seconds, on macOS 27.0.1 (Apple M3):
| n | main (debug build) | main + fix (debug build) | 3.15.0 (release, for comparison) |
|---|---|---|---|
| 8000 | 0.050 | 0.011 | 0.010 |
| 16000 | 0.153 | 0.002 | 0.004 |
| 32000 | 0.598 | 0.004 | 0.007 |
| 64000 | 2.373 | 0.008 | 0.015 |
The sample ('a,b' + ' ' * 100_000 + 'c"\n') * 4 takes 23.2 s on main and 0.06 s with the fix.
The cause is the regex in Sniffer._split_dormant() (Lib/csv.py):
m = re.compile(fr'(?:^|([\r\n{cls}]))'
fr' *{quotechar}').search(part, pos)
The space is a delimiter candidate whenever the sample contains one, so it is in cls. The search then tries a match at every space of the run: [...] matches that space, * consumes the rest of the run, and the match fails on the next character. A run of n spaces costs O(n**2).
A match that starts at a space preceded by a space is never the leftmost one: a match with the same group and the same end also starts at the beginning of the run. Adding the lookbehind (?<! ) after the group skips those positions without changing any result.
This was introduced in gh-83273 (25fea6d64e1) and is in 3.16.0a1. 3.15 and older are not affected.
CPython versions tested on:
3.15, CPython main branch
Operating systems tested on:
macOS
Linked PRs
- gh-160557
- 主要语言
- Python
- 星标
- 77.7k
- 派生
- 38.3k
- 平均合并
- 13 小时 43 分钟
- 30 天内合并 PR
- 704
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
python/cpython 的其他 Issue
-
topic-socket type-bug
难度 2/5 1-3 小时 新手友好度 72/100
python/cpython#160561 · 7 条评论 ·
维护者通常 1 天内回复
-
tests topic-profiling type-bug
难度 2/5 1-3 小时 新手友好度 78/100
python/cpython#160334 · 1 条评论 ·
维护者通常 1 天内回复
-
`iso2022_jp_3` encodes U+9B1D but decodes the result as U+9B1C可能已有人在做 @kinqsradio 今天认领。 未关闭extension-modules type-bug
难度 2/5 1-3 小时 新手友好度 84/100
维护者通常 1 天内回复
-
interpreter-core type-feature
难度 1/5 1 小时以内 新手友好度 78/100
python/cpython#160109 · 1 条评论 ·
维护者通常 1 天内回复
-
extension-modules type-bug
难度 2/5 1-3 小时 新手友好度 72/100
python/cpython#160001 · 3 条评论 ·
维护者通常 1 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
scikit-learn-contrib/category_encoders#553 ·
维护者通常 1 天内回复
-
flaky-watch
难度 2/5 1-3 小时 新手友好度 88/100
btclib-org/btclib#2839 ·
维护者通常 1 天内回复
-
BarrelList constructor drops false-valued iterable contents可能已有人在做 @Gambit-Checkmate 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 19 天内回复
-
难度 2/5 1-3 小时 新手友好度 77/100
vllm-project/vllm#63863 ·
维护者通常 1 天内回复