perf(buffer): toBuffer ArrayBuffer→Buffer 用 Buffer.from 零拷贝替代逐字节循环

千字文 ttf 0.396ms→0.252ms(-36%),woff2 不受影响(不走 node Buffer 路径)。
Writer 的 ArrayBuffer 精确分配为 ttfSize(offset=0),getBuffer 返回完整 buffer,
Buffer.from 共享底层内存无 over-exposure 风险。SSIM 全部不变。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
崮生(子虚) 2026-07-24 09:15:17 +08:00
parent 69dc5e343e
commit ece6eeca2f
3 changed files with 30 additions and 7 deletions

8
_prof.entry.ts Normal file
View File

@ -0,0 +1,8 @@
import { readFileSync } from 'fs';
import { fontSubset } from './backend/font_util/font.js';
const buf = readFileSync('font/令东齐伋复刻体.ttf');
const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
const text = '天地玄黄宇宙洪荒日月盈昃辰宿列张寒来暑往秋收冬藏闰余成岁律吕调阳云腾致雨露结为霜金生丽水玉出昆冈剑号巨阙珠称夜光果珍李柰菜重芥姜海咸河淡鳞潜羽翔';
fontSubset(ab, text, { sourceType: 'ttf', outType: 'ttf' });
const N = 500;
for (let i = 0; i < N; i++) fontSubset(ab, text, { sourceType: 'ttf', outType: 'ttf' });

16
_speed.entry.ts Normal file
View File

@ -0,0 +1,16 @@
import { performance } from 'perf_hooks';
import { readFileSync } from 'fs';
import { fontSubset } from './backend/font_util/font.js';
const buf = readFileSync('font/令东齐伋复刻体.ttf');
const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
const cases: [string,string,any][] = [
['千字文woff2','天地玄黄宇宙洪荒日月盈昃辰宿列张寒来暑往秋收冬藏闰余成岁律吕调阳云腾致雨露结为霜金生丽水玉出昆冈剑号巨阙珠称夜光果珍李柰菜重芥姜海咸河淡鳞潜羽翔',{sourceType:'ttf',outType:'woff2'}],
['千字文ttf','天地玄黄宇宙洪荒日月盈昃辰宿列张寒来暑往秋收冬藏闰余成岁律吕调阳云腾致雨露结为霜金生丽水玉出昆冈剑号巨阙珠称夜光果珍李柰菜重芥姜海咸河淡鳞潜羽翔',{sourceType:'ttf',outType:'ttf'}],
];
for (const [label,text,opt] of cases) {
fontSubset(ab, text, opt);
const N = 300;
const t0 = performance.now();
for (let i=0;i<N;i++) fontSubset(ab, text, opt);
console.log(`${label.padEnd(14)} avg=${((performance.now()-t0)/N).toFixed(3)}ms`);
}

View File

@ -30,16 +30,15 @@ var _default = exports.default = {
* @param {ArrayBuffer} arrayBuffer 缓冲数组
* @return {Buffer}
*/
/**
* 优化311: ArrayBufferBuffer Buffer.from 共享底层内存零拷贝
* 替代逐字节 view.getUint8 循环千字文 ttf 162KB 输出时为 toBuffer 9% 热点
* write 产出的 ArrayBuffer 后续不再修改共享安全
*/
toBuffer: function toBuffer(arrayBuffer) {
if (Array.isArray(arrayBuffer)) {
return Buffer.from(arrayBuffer);
}
var length = arrayBuffer.byteLength;
var view = new DataView(arrayBuffer, 0, length);
var buffer = Buffer.alloc(length);
for (var i = 0, l = length; i < l; i++) {
buffer[i] = view.getUint8(i, false);
}
return buffer;
return Buffer.from(arrayBuffer);
}
};