用一个近似式加小修正表,把枚举转字符串的偏移表再压一半
来源:corsix.org — 2026-10-21
📋 概述
把枚举转成字符串的 switch,在 -O2 以上会被 GCC 改写成指针数组,但指针表加上重定位项太占空间。常见优化是把所有字符串拼成一段连续内存,改用 uint16 偏移表。作者再进一步:偏移随枚举值近似线性增长,先用 x*17 这样的线性近似,再用一张小修正表兜住 [-9,+10] 的误差,于是原来的偏移表被更小的修正表取代。
🔑 核心要点
- switch 版本在 -O0/-O1 下汇编很难看,-O2 起编译器自动折成 静态指针数组 + 边界检查
- 指针换成相对偏移的理由很实在:相对偏移比指针小得多,还省掉每条表项的重定位项
- 对 0→0、22→382 这组数据,取整斜率 382/22 得到 17,x*17 与真实偏移的差恒定落在 [-9,+10],用 int8 就够存
- 这是「先近似再纠偏」的通用手法:把一张大表拆成一个乘加运算加一张小表,适用于任何单调但非线性的查表
💡 金句
It is rarely the case that x * 17 exactly equals offsets[x], but the difference happens to always end up being in the range [-9, +10].
👍 0
👎 0
← 返回 Lobsters 首页