perf(gsub): readCoverageRemapped 跳过损坏 coverage 的空循环

FiraCode subsetGSUB 的 readCoverageRemapped 占 70.5% self time。插桩定位:
77 次 format1 miss 中有 8 次 count 高达 15460(远超字体 glyph 总数 1652),
这些是 ChainContextSubst format3 指向错误偏移读到的垃圾 count,原代码循环
count 次全部 gidLookup[g] 越界返回 undefined 被跳过,浪费 107852 次迭代
(占 format1 miss 总工作量的 95%)。

count > numGlyphs 时跳过必然全空的循环,仅保留 origNonEmpty=count>0 语义
→ newGids 空 → outOfSubset=true → 返回 null,与原代码循环全空结果完全等价。
基准 29 用例 SSIM/ink/字节全无回归,FiraCode fontSubset 12.2ms→6.8ms(-45%)。

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

View File

@ -177,17 +177,30 @@ function readCoverageRemapped(
const format = dv.getUint16(off, false);
if (format === COV_LIST) {
const count = dv.getUint16(off + 2, false);
/** / coverage coverage gid glyph indexcount glyph
* = gidLookup.lengthFiraCode 77 format1 miss 8 count 15460
* glyph 1652 ChainContextSubst format3 count
* 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 */
const numGlyphs = gidLookup.length;
const base = off + 4;
if (base + count * 2 <= len) {
if (base + count * 2 > len) {
/** 数据范围越界原代码不进入循环origNonEmpty 保持 false返回空数组 */
} else if (count > numGlyphs) {
/** coveragecount glyph gidLookup
* origNonEmpty=count>0 newGids outOfSubset=true null */
origNonEmpty = count > 0;
} else {
origNonEmpty = count > 0;
/** 预分配最大容量 count索引写入后截断长度避免 push 动态扩容format1 是 coverage 热路径) */
const buf = new Array(count);
let w = 0;
/** coverage format1 gid count u16
* DataView.getUint16 + gid 2
* Uint16Array view buffer + hmtx/loca
* readCoverageRemapped FiraCode subsetGSUB 75.5%miss
* sum ~26000 gid DataView */
* Uint16Array view buffer + hmtx/loca */
const gidArrByteOff = dv.byteOffset + base;
if ((gidArrByteOff & 1) === 0) {
const src16 = new Uint16Array(dv.buffer, gidArrByteOff, count);