perf(gsub): readCoverageRemapped format2 range clamp 到 numGlyphs

承接 fda7ab8(format1 损坏 coverage 跳过)。插桩定位剩余 miss 热点:format2
(range) 仅 11 次 miss,但 439 个 range 的 end >= numGlyphs(1652),逐 gid 展开
浪费 ~320 万次 gidLookup 索引(全部 g>=numGlyphs 越界跳过),是 readCoverageRemapped
剩余 55% self time 的绝大头。

将每个 range 的 end clamp 到 numGlyphs-1:start..numGlyphs-1 段与原代码逐 gid 处理
完全相同,numGlyphs..end 段原代码全越界跳过、clamp 后省去空循环。整个 range 越界
(start>=numGlyphs) 时保留 origNonEmpty=true 语义(→ outOfSubset → null),与原代码
逐 gid 遍历全空结果完全等价。

基准 29 用例 SSIM/ink/字节全无回归,FiraCode fontSubset 6.8ms→3.75ms(累计较
优化前 12.2ms -69%)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
崮生(子虚) 2026-07-23 20:39:12 +08:00
parent fda7ab8902
commit 7d62bce1df

View File

@ -183,8 +183,7 @@ function readCoverageRemapped(
* count gidLookup[g] undefined >=0 107852
* readCoverageRemapped 95%
* count > 0 origNonEmpty=true newGids outOfSubset=true null
* coverage/subtable
* readCoverageRemapped FiraCode subsetGSUB 70.5% self time */
* coverage/subtable */
const numGlyphs = gidLookup.length;
const base = off + 4;
if (base + count * 2 > len) {
@ -221,16 +220,31 @@ function readCoverageRemapped(
}
} else if (format === COV_RANGE) {
const rangeCount = dv.getUint16(off + 2, false);
/** range end = glyph - 1gidLookup[g] g >= numGlyphs
* range end clamp numGlyphs-1start >= numGlyphs range
* gid
* FiraCode 11 format2 miss 439 end >= numGlyphs range gid
* ~320 gidLookup readCoverageRemapped */
const numGlyphs = gidLookup.length;
let p = off + 4;
for (let i = 0; i < rangeCount; i++) {
if (p + 6 > len) break;
const start = dv.getUint16(p, false);
const end = dv.getUint16(p + 2, false);
if (end >= start && end - start < COVERAGE_MAX_EXPAND && newGids.length + (end - start + 1) <= COVERAGE_MAX_EXPAND) {
for (let g = start; g <= end; g++) {
if (start >= numGlyphs) {
/** range gid push origNonEmpty=true
* newGids origNonEmpty=true outOfSubset null */
origNonEmpty = true;
const m = gidLookup[g];
if (m >= 0) newGids.push(m);
} else {
/** clamp end gid start..numGlyphs-1 gid
* numGlyphs..end clamp */
const e = end < numGlyphs ? end : numGlyphs - 1;
for (let g = start; g <= e; g++) {
origNonEmpty = true;
const m = gidLookup[g];
if (m >= 0) newGids.push(m);
}
}
}
p += 6;