perf(gsub-reachable): collectChainRefs format3 短路 + 去闭包/中间数组

固定点迭代中 collectChainRefs 高频调用(初夏纯标点 840 次/call)。format3 原实现:
读完全部 backtrack/input/lookahead coverage 把 gid 收进 allGids 中间数组,任一不在
子集才置 triggerable=false,且每次调用分配 readCovGids 闭包 + allGids 数组。

优化:遇到不在子集的 gid 立即短路返回(triggerable=false 时 contextGids/refs 本就不
收集,后续 coverage 无需再读);去掉闭包与 allGids,triggerable 时 gid 直接 add 进
contextGids。逻辑完全等价(triggerable=false 时原代码也不 add contextGids)。

基准 29 用例 SSIM/ink/字节全无回归。初夏纯标点 2.34→1.86ms(-20%),FiraCode 3.7→3.4ms。

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

View File

@ -302,29 +302,36 @@ function collectChainRefs(
}
} else if (format === 3) {
/** format3: coverage + SubstLookupRecords
* coverage backtrack/input/lookahead gid */
* coverage backtrack/input/lookahead gid
* triggerable false coverage
* readCovGids + allGids collectChainRefs
* 840 /calltriggerable gid add contextGids allGids */
let p = off + 2;
const allGids: number[] = [];
let triggerable = true;
const readCovGids = (cnt: number): boolean => {
const readCovGidsChecked = (cnt: number): void => {
for (let k = 0; k < cnt; k++) {
const covGids = readCoverageGids(r, off + r.u16(p + k * 2), covCache);
for (const g of covGids) {
allGids.push(g);
if (!inSubset(g)) triggerable = false;
if (!inSubset(g)) {
triggerable = false;
return;
}
contextGids.add(g);
}
}
p += cnt * 2;
return true;
};
const backtrackCount = r.u16(p); p += 2;
readCovGids(backtrackCount);
const inputCount = r.u16(p); p += 2;
readCovGids(inputCount);
const lookaheadCount = r.u16(p); p += 2;
readCovGids(lookaheadCount);
readCovGidsChecked(backtrackCount);
if (triggerable) {
const inputCount = r.u16(p); p += 2;
readCovGidsChecked(inputCount);
}
if (triggerable) {
const lookaheadCount = r.u16(p); p += 2;
readCovGidsChecked(lookaheadCount);
}
if (triggerable) {
for (const g of allGids) contextGids.add(g);
const substCount = r.u16(p);
for (let k = 0; k < substCount; k++) refs.add(r.u16(p + 2 + k * 4 + 2));
}