perf(gsub-reachable): type1 fmt2 反转遍历方向

collectSubtableTargets 的 SingleSubst format2 原遍历 coverage gid
逐个查 reachable(inSubset=Set.has)。初夏明朝纯标点实测 fmt2 covLen
合计 9180 gid/round,但 reachable 仅 53 → 命中率 <4%,9180 次 Set.has
几乎全 miss。

反转:遍历 reachable(小集合)二分查找 covGids(按 gid 升序,fmt1 list
/ fmt2 range 展开均天然排序)得 index,命中则读 gidArray[i]。遍历量从
covGids.length 降到 reachable.size。

A/B(3000 次 p50):
- 初夏标点 129→105μs(-19%)
- 初夏8字 64→58μs(-9%)
- 霞鹜标点 13→11μs(-13%)
- 霞鹜8字 7.8→6.6μs(-15%)

reachable 集合 sha256 全部一致,基准测试 SSIM 全不变。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
崮生(子虚) 2026-07-24 17:03:26 +08:00
parent fee9e49164
commit 9d6e982682

View File

@ -224,7 +224,7 @@ export function collectReachableGsubTargets(
const refLk = lookups[li];
if (!refLk) continue;
for (const refSub of refLk.subtableAbsOffs) {
const refTargets = collectSubtableTargets(r, refSub, refLk.effectiveType, inSubset, covCache);
const refTargets = collectSubtableTargets(r, refSub, refLk.effectiveType, inSubset, covCache, reachable);
for (const g of refTargets) {
if (!reachable.has(g)) { reachable.add(g); changed = true; }
}
@ -238,7 +238,7 @@ export function collectReachableGsubTargets(
failGidMap.set(subAbs, failGidBox.v);
}
} else {
const newTargets = collectSubtableTargets(r, subAbs, lk.effectiveType, inSubset, covCache);
const newTargets = collectSubtableTargets(r, subAbs, lk.effectiveType, inSubset, covCache, reachable);
for (const g of newTargets) {
if (!reachable.has(g)) {
reachable.add(g);
@ -261,6 +261,7 @@ function collectSubtableTargets(
type: number,
inSubset: (gid: number) => boolean,
covCache: CoverageCache,
reachable: Set<number>,
): number[] {
const targets: number[] = [];
if (type === LT_SINGLE) {
@ -274,9 +275,22 @@ function collectSubtableTargets(
if (inSubset(g)) targets.push((g + delta) & 0xffff);
}
} else if (format === 2) {
/** coverageavg 103 gid <4% reachable 53
* covGids reachable 9180 Set.has/round reachable covGids index
* covGids gid fmt1 list / fmt2 range */
const count = r.u16(off + 4);
for (let i = 0; i < covGids.length && i < count; i++) {
if (inSubset(covGids[i])) targets.push(r.u16(off + 6 + i * 2));
const lim = covGids.length < count ? covGids.length : count;
const gidArrBase = off + 6;
for (const g of reachable) {
/** 二分 covGids[0..lim) 找 g 的 index */
let lo = 0, hi = lim;
while (lo < hi) {
const mid = (lo + hi) >> 1;
const mg = covGids[mid];
if (mg < g) lo = mid + 1;
else if (mg > g) hi = mid;
else { targets.push(r.u16(gidArrBase + mid * 2)); break; }
}
}
}
} else if (type === LT_MULTIPLE) {