sansenandClaude Code b264073f2b 大交替串加首字符预筛:convert_text 提速 3.05x,输出零差异
CPython 的 re 不对大交替串 (?:A|B|...) 做首字符预筛——460 个年号的交替串在每个
位置都要把全部分支逐个试完才移向下一位。实测这类扫描占 convert_text 总耗时的 82%
(sample_2.txt 1.03M 字符:扫描 7.05 / 总计 8.54 µs/字符),而其中多数模式只命中
0~134 处。

改法:给每个"以年号或朝代名开头"的模式前面加一个零宽前瞻 (?=[首字集合])。前瞻不
消耗字符,只在当前位置断言下一个字符属于集合。预筛字符集从与模式**同一份源数据**
推导(_dynasty_names / _dynasty_prefix / KNOWN_ERAS_ALL),CSV 加新年号时自动同步。
三种预筛:_GATE_DYNASTY(朝代组必选)/ _GATE_DYNASTY_OPT(_dynasty_opt 可空)/
_GATE_ERA(朝代组为空)。

结果为什么不变(结构性保证,非经验之谈):前瞻只拒绝「原模式根本不可能开始匹配」的
位置 → 匹配集合完全相同 → 捕获组相同 → 后续执行序列一致 → 输出逐字段一致。

不加预筛者(前提不满足):公元段(前缀整个可选)、裸干支段(以干支对开头)、
民国段(以字面量 民 开头,re 自带前缀优化)。

顺带把 2b/3/3b 段的 4 个正则从 extract_era_years 内提到模块级:只编译一次,且差分
测试能取到它们。

验证:
- 全字段快照比对:sample.txt 1766 / sample_2.txt 20188 / test/sample.txt 14 /
  test/sample_crosscheck.txt 11,全部 19 个字段逐条一致,零差异
- pytest 260 passed(新增 TestFirstCharGate 3 条)、summary.py 96/96
- 速度:sample_2.txt 8.53s → 2.80s(3.05x)、sample.txt 0.64s → 0.21s(2.99x)
- 3.8.10 下编译通过(部署目标)
- 变异测试:手动砍掉预筛里一个首字符后,差分测试立即失败并指出漏掉的 "万历二十三年"
  —— 证明这道护栏真的能挡住坏的预筛

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 17:14:13 +08:00
2026-07-16 11:08:40 +08:00
2026-08-07 16:12:59 +08:00
2026-08-07 16:12:59 +08:00
S
Description
No description provided
Readme
251 KiB
Languages
Python 100%