mirror of
https://github.com/2234839/web-font.git
synced 2026-09-04 23:02:27 +08:00
perf(gsub-reachable): collectReachableGsubTargets 单 Set inSubset + 复用临时 Set
初夏明朝纯标点(最慢 CJK 用例 4ms)profile 显示 collectReachableGsubTargets 占 19.2% + collectChainRefs 7.8%(合计 27%,超过 subsetGSUB 本身 6.4% 的 3 倍)。单次 1.22ms。 优化: 1. inSubset 闭包原为 seedGids.has(g) || reachable.has(g) 两次 Set 查询(热路径每 subtable 多次调用)。改为 reachable 初始即含 seedGids,inSubset 只查 reachable 一个 Set。 返回的 reachable 可能含 seed gid——调用方注入 extraSubsetGids 后 Font.create 去重,无害。 2. 每个 type6 subtable 原 new Set() × 2(refs + ctxGids),多轮迭代 × 51 lookup 累积 GC 压力。 改为循环外复用 + clear。 实测初夏明朝 1.22→1.02ms(-16%),FiraCode 0.75→0.69ms(-8%)。 基准测试 29 用例 SSIM/ink/输出字节全部无回归(初夏纯标点 4.4→3.6ms)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bbc3d8b88a
commit
6ea19550a1
@ -116,11 +116,19 @@ export function collectReachableGsubTargets(
|
||||
* type6 ChainedContext 规则:若其全部 input/backtrack/lookahead gid 都在子集内,
|
||||
* 则规则可触发——此时被引用 lookup 的 target 需保留(通过 chainRefs 在迭代中处理 type1/2/3/4 target)。
|
||||
* type1/2/3/4 规则:coverage gid 在子集 → target 保留。
|
||||
* 这模拟了 pyftsubset 的「实际触发路径」分析,避免保留无关 calt 规则的海量 context glyph。 */
|
||||
const reachable = new Set<number>();
|
||||
* 这模拟了 pyftsubset 的「实际触发路径」分析,避免保留无关 calt 规则的海量 context glyph。
|
||||
*
|
||||
* 优化(单 Set inSubset):reachable 初始即含 seedGids,inSubset 只查 reachable 一个 Set
|
||||
* (原为 seedGids.has || reachable.has 两次 Set 查询,热路径每 subtable 多次调用)。
|
||||
* 返回的 reachable 可能含 seed gid——调用方注入 extraSubsetGids 后 Font.create 会去重,无害。 */
|
||||
const reachable = new Set<number>(seedGids);
|
||||
let changed = true;
|
||||
/** 当前「在子集内」的 gid 集合 = seed ∪ reachable */
|
||||
const inSubset = (gid: number) => seedGids.has(gid) || reachable.has(gid);
|
||||
/** 当前「在子集内」= reachable(已含 seed) */
|
||||
const inSubset = (gid: number) => reachable.has(gid);
|
||||
|
||||
/** 复用临时 Set,避免每个 type6 subtable 两次 new Set 的 GC 压力(初夏明朝 51 lookup 多轮迭代) */
|
||||
const refsReuse: Set<number> = new Set<number>();
|
||||
const ctxGidsReuse: Set<number> = new Set<number>();
|
||||
|
||||
while (changed) {
|
||||
changed = false;
|
||||
@ -129,13 +137,13 @@ export function collectReachableGsubTargets(
|
||||
for (const subAbs of lk.subtableAbsOffs) {
|
||||
if (lk.effectiveType === LT_CHAIN) {
|
||||
/** type6:收集可触发规则引用的 lookup index 与所需 context gid */
|
||||
const refs = new Set<number>();
|
||||
const ctxGids = new Set<number>();
|
||||
collectChainRefs(r, subAbs, refs, ctxGids, inSubset, covCache);
|
||||
for (const g of ctxGids) {
|
||||
refsReuse.clear();
|
||||
ctxGidsReuse.clear();
|
||||
collectChainRefs(r, subAbs, refsReuse, ctxGidsReuse, inSubset, covCache);
|
||||
for (const g of ctxGidsReuse) {
|
||||
if (!reachable.has(g)) { reachable.add(g); changed = true; }
|
||||
}
|
||||
for (const li of refs) {
|
||||
for (const li of refsReuse) {
|
||||
const refLk = lookups[li];
|
||||
if (!refLk) continue;
|
||||
for (const refSub of refLk.subtableAbsOffs) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user