web-font/_p_write.ts
崮生(子虚) 8a7efea9d0 perf(gpos/gsub): read 零拷贝 subarray 替代 readBytes slice
GPOS/GSUB 表类 read 原用 reader.readBytes (= new Uint8Array(view.buffer, off, len).slice()),
.slice() 拷贝整个表字节(初夏 GPOS 68KB、GSUB 31KB)。V8 中 68KB slice 耗 ~40μs,
而 subarray 零拷贝仅 ~0.3μs(130× 差距)。

GPOS/GSUB 是原始字节透传:subsetGPOS/subsetGSUB 只读 OTReader + 写全新 OTWriter,
write 只 writeBytes 只读,optimize 不碰,整个 read→optimize→subset→write 生命周期
从不原地修改底层字节,故可安全返回共享 ArrayBuffer 的 subarray 视图。

初夏 full read 0.124→0.063ms (-49%),readBuffer 0.165→0.098ms。
全基准 SSIM 与输出字节完全不变。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-24 15:07:18 +08:00

29 lines
1.5 KiB
TypeScript

import fs from 'node:fs';
import { Font } from './vendor/fonteditor-core/lib/ttf/font.js';
function median(a: number[]) { return a.slice().sort((x,y)=>x-y)[Math.floor(a.length/2)]; }
function bench(label: string, fn: () => void, iters = 9) {
for (let i = 0; i < 3; i++) fn();
const ts: number[] = [];
for (let i = 0; i < iters; i++) { const t0 = performance.now(); fn(); ts.push(performance.now() - t0); }
console.log(`${label}: ${median(ts).toFixed(3)}ms (min ${Math.min(...ts).toFixed(3)})`);
}
for (const [name, p, text] of [
['初夏标点', '/mnt/d/字体资源/初夏明朝/初夏明朝-Regular.ttf', ',。!?、;:“”‘’'],
['思源8字', './font/思源黑体.ttf', '天地玄黄宇宙洪荒'],
['令东千字', './font/令东齐伋复刻体.ttf', '天地玄黄宇宙洪荒日月盈昃辰宿列张寒来暑往秋收冬藏闰余成岁律吕调阳云腾致雨露结为霜金生丽水玉出昆冈'],
] as const) {
const buf = fs.readFileSync(p);
const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset+buf.byteLength) as ArrayBuffer;
const cps = Array.from(text);
console.log(`\n=== ${name} (${text.length}字) ===`);
bench(' create', () => Font.create(ab, { type: 'ttf', subset: cps as any, kerning: true }));
const font = Font.create(ab, { type: 'ttf', subset: cps as any, kerning: true });
const opt = (font as any).optimize();
bench(' write-woff2', () => opt.write({ type: 'woff2', hinting: false } as any));
// write-ttf 对比
bench(' write-ttf', () => opt.write({ type: 'ttf', hinting: false } as any));
}