Skip to content

Convert all regexes to source-generated regexes - #7

Merged
rabbitism merged 1 commit into
mainfrom
perf/generated-regex
Sep 7, 2026
Merged

rabbitism merged 1 commit into
mainfrom
perf/generated-regex

Conversation

@rabbitism

Copy link
Copy Markdown
Member

概述

将全部 17 处 RegexOptions.Compiled 正则迁移为 [GeneratedRegex] 源生成版本(JiebaSegmenter 5、PosSegmenter 7、FinalSeg Viterbi 2、Extensions 1,删除 2 个无引用正则)。

动机

  1. NativeAOT(主要收益):RegexOptions.Compiled 依赖首次使用时的 Reflection.Emit,NativeAOT 下不可用并静默回退到解释执行。最热的 CJK 分块正则(每次 Cut 都在 Split+IsMatch)在 AOT 发布里一直跑的是慢速解释器;源生成版本是纯 C# 匹配代码,AOT 下原生全速。
  2. 冷启动:消除 13 个模式首次使用时的逐个 ReflexCompile 成本。
  3. 稳态:JIT 下与 Compiled 基本持平(实测无回退),GC/分配不变。

TFM 已只剩 net8.0/net10.0,[GeneratedRegex](C# 11/net7+)的版本障碍不再存在。JiebaSegmenter / PosSegmenter / Viterbi / Extensions 转为 partial,调用点由字段访问改为方法调用;删除已无引用的 RegexEnglishChars 与 RegexNewline。

验证

  • 全量 123 个测试(含逐字比对)通过;NativeAOT 冒烟通过。
  • JIT 稳态基准(medium 场景)与转换前持平(差异在运行噪声内),vs 上游仍为 1.26x~1.68x。
  • 冷启动 ~800ms 量级不变(正则首编译的节省相对词典加载占比小,属预期)。

RegexOptions.Compiled depends on Reflection.Emit at first use, which is
unavailable under NativeAOT - there the engine silently falls back to
the slow interpreter, and the hottest pattern (the CJK block splitter
that runs on every Cut) pays that cost on every match. Generated
regexes emit plain matching code that AOT compiles natively, and they
also remove the lazy per-pattern compile cost from first use.

Also delete two regexes that no longer have references.
@rabbitism

Copy link
Copy Markdown
Member Author
Scenario fork ms upstream ms upstream / fork fork alloc upstream alloc
'Cut accurate no-HMM medium' 0.367 0.689 1.88 659.86 KB 859.3 KB
'Cut accurate no-HMM short' 0.004 0.009 2.11 12.17 KB 15.18 KB
'Cut accurate+HMM large (novel)' 156.34 218.278 1.4 167747.18 KB 185949.44 KB
'Cut accurate+HMM medium' 0.491 0.806 1.64 871.91 KB 1059.15 KB
'Cut accurate+HMM short' 0.006 0.011 1.64 15.3 KB 18.21 KB
'CutAll large (novel)' 91.559 125.784 1.37 66798.31 KB 70972.69 KB
'CutAll medium' 0.318 0.443 1.39 535.33 KB 580.16 KB
'CutAll short' 0.004 0.006 1.57 9.58 KB 10.43 KB
'CutForSearch medium' 0.546 0.862 1.58 917.12 KB 1111.2 KB
'POS cut medium' 4.169 5.769 1.38 1924.68 KB 2500.68 KB
'TextRank keywords medium' 6.029 7.59 1.26 2312.32 KB 2906.95 KB
'TF-IDF keywords medium' 0.639 0.945 1.48 928.81 KB 1116.05 KB

@rabbitism
rabbitism merged commit 900ce83 into main Sep 7, 2026
5 checks passed
@rabbitism
rabbitism deleted the perf/generated-regex branch September 7, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant