From 7b5d03391f4070188bde1df7d35e606d31e38edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B4=AE=E7=94=9F=EF=BC=88=E5=AD=90=E8=99=9A=EF=BC=89?= <2234839456@qq.com> Date: Fri, 24 Jul 2026 17:49:42 +0800 Subject: [PATCH] =?UTF-8?q?perf(gsub-reachable):=20type4=20Ligature=20firs?= =?UTF-8?q?t=20gid=20=E7=9F=AD=E8=B7=AF=E8=B7=B3=E8=BF=87=E6=95=B4?= =?UTF-8?q?=E4=B8=AA=20LigatureSet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LigatureSubst 第一分量(coverage gid)不在子集时整条 ligature 不会触发, 原实现在 first 不在子集时仍读取 setOff/ligCount/每条 ligature 的 ligOff/compCount/target 后才 continue。改为 first 检查上提到 LigatureSet 展开之前,不在子集直接跳过,省掉内部全部 u16 读取。 初夏明朝 type4 first gid 常全不在子集(首轮 coverage 多为非子集字形), 此短路消除每条 ligature 的无谓读取。 collectReachableGsubTargets min(checksum 与改动前完全一致): - 初夏汉字标点 0.070→0.059ms(-16%) - 初夏纯标点 0.081→0.068ms(-15%) - FiraCode 0.105→0.101ms(-4%) 全字体 SSIM/输出字节均不变。 Co-Authored-By: Claude Opus 4.8 (1M context) --- backend/font_util/gsub-reachable.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/backend/font_util/gsub-reachable.ts b/backend/font_util/gsub-reachable.ts index f334a0a..cbdd4f0 100644 --- a/backend/font_util/gsub-reachable.ts +++ b/backend/font_util/gsub-reachable.ts @@ -360,15 +360,17 @@ function collectSubtableTargets( const setCount = r.u16(off + 4); const covGids = readCoverageGids(r, covOff, covCache); for (let i = 0; i < covGids.length && i < setCount; i++) { - const firstInSubset = inSubset(covGids[i]); + /** 第一分量(coverage gid)不在子集时整条 ligature 不触发,跳过整个 LigatureSet, + * 不展开其内部 ligature(省 ligCount/ligOff/compCount/target 等无谓 u16 读取)。 + * 初夏明朝 type4 first gid 常全不在子集(首轮覆盖 glyph 多为非子集字形),此短路省掉每条 + * ligature 的多次 u16 读 + inSubset 判定。 */ + if (!inSubset(covGids[i])) continue; const setOff = off + r.u16(off + 6 + i * 2); const ligCount = r.u16(setOff); for (let j = 0; j < ligCount; j++) { const ligOff = setOff + r.u16(setOff + 2 + j * 2); const compCount = r.u16(ligOff); const target = r.u16(ligOff + 2); - /** 第一分量需在子集(若 first 不在子集,整条 ligature 不会触发) */ - if (!firstInSubset) continue; let allIn = true; for (let k = 0; k < compCount - 1; k++) { if (!inSubset(r.u16(ligOff + 4 + k * 2))) {