web-font/基准测试_llrt.ts
崮生(子虚) 6f0e3d8e6b fix: 修复 name 表写入偏移错误导致浏览器无法渲染字体
name.js write 函数改用 view.setUint16 后未同步 writer.offset,
导致 name 字符串覆盖 header,name 表损坏。浏览器依赖 name 表
识别字体所以无法渲染,而 Node 端渲染不依赖 name 表所以基准
测试未检测到。

同时修复 cmap sizeof 动态计算记录头大小的问题。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 11:22:51 +08:00

78 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* LLRT 字体裁剪 — 生成子集字体供 Node 渲染验证
* 运行: pnpm build_backend && ./llrt dist_backend/llrt_bench.lrt
*/
import { readFile, writeFile, mkdir } from "node:fs/promises";
import { performance } from "node:perf_hooks";
import { Font } from "./vendor/fonteditor-core/lib/ttf/font.js";
const FONT_PATH = "font/令东齐伋复刻体.ttf";
const FONT_NAME = "令东齐伋复刻体";
const BENCHMARK_DIR = "benchmark_results";
const testCases = [
{ label: "8个汉字", text: "天地玄黄宇宙洪荒" },
{ label: "拉丁+数字", text: "Hello World 123" },
{ label: "千字文前段", text: "天地玄黄宇宙洪荒日月盈昃辰宿列张寒来暑往秋收冬藏闰余成岁律吕调阳云腾致雨露结为霜金生丽水玉出昆冈剑号巨阙珠称夜光果珍李柰菜重芥姜海咸河淡鳞潜羽翔" },
];
const ROUNDS = 10;
async function main() {
const raw = await readFile(FONT_PATH);
const fontBuffer = new Uint8Array(raw).buffer;
await mkdir(BENCHMARK_DIR, { recursive: true });
console.log("\n=== LLRT 字体裁剪验证 ===\n");
console.log("[runtime]", globalThis.process?.release?.name ?? "unknown");
console.log("[font]", FONT_PATH, "size:", fontBuffer.byteLength, "bytes\n");
const summary: Array<{ label: string; text: string; avg: number; min: number; max: number; outputSize: number; fontFile: string }> = [];
for (const { label, text } of testCases) {
const subset = [...text].map((c) => c.codePointAt(0)!);
const times: number[] = [];
let lastOutput: Uint8Array | null = null;
for (let i = 0; i < ROUNDS; i++) {
const t0 = performance.now();
const font = Font.create(fontBuffer, { type: "ttf", subset });
const optimized = font.optimize().sort();
const result = optimized.write({ type: "ttf" });
const t1 = performance.now();
times.push(t1 - t0);
if (i === 0) {
lastOutput = typeof result === "string"
? new TextEncoder().encode(result)
: new Uint8Array(result);
}
}
const avg = times.reduce((a, b) => a + b, 0) / times.length;
const min = Math.min(...times);
const max = Math.max(...times);
const size = lastOutput?.length ?? 0;
/** 保存子集字体文件 */
const safeLabel = label.replace(/[^a-zA-Z0-9\u4e00-\u9fff]/g, "_");
const fontFile = `${BENCHMARK_DIR}/llrt_${safeLabel}.ttf`;
if (lastOutput) {
await writeFile(fontFile, lastOutput);
}
summary.push({ label, text, avg, min, max, outputSize: size, fontFile });
console.log(` ${label}: avg=${avg.toFixed(1)}ms min=${min.toFixed(1)}ms max=${max.toFixed(1)}ms 输出=${size.toLocaleString()} bytes`);
}
await writeFile(
`${BENCHMARK_DIR}/llrt_bench_meta.json`,
JSON.stringify({ runtime: globalThis.process?.release?.name, fontPath: FONT_PATH, fontName: FONT_NAME, rounds: ROUNDS, results: summary }, null, 2),
);
console.log("\n子集字体已保存请运行: pnpm tsx 基准测试_verify.ts");
}
main();