来源: ranxianglei/billion-context#478 分析 sessions 启动解析开销时发现
背景
billion-context#478 修复了 sessions 注册表存储的三重膨胀(叶块 blockContents 逐字节双份、零 GC、每次启动两遍全量同步解析)。其中"启动解析时间随语料规模线性恶化"目前只能治一半:启动期 GC 把语料总量封顶(默认 1 GiB)之后,每次启动仍然要对全部存活文件做 readFileSync + JSON.parse(kernel loadAll 全量递归目录树,逐文件解析)。语料封顶在 GB 量级时,单次启动的同步解析仍是百毫秒~秒级开销,且随会话数线性增长。
billion-context 侧无法绕过:选择性加载需要复刻 kernel 的 canonical/spill(<name>.fb.json)savedAt 对账("freshest wins")逻辑,属于对 kernel 内部实现的脆弱复制,不可取。
建议(二选一,均纯增量、默认行为不变)
loadAll(options?: { maxParseBytes?: number }):先只 readdir + stat(不读内容),按文件大小/mtime 从新到旧累加,超过预算的最旧文件跳过解析;或
- 暴露
statAll(): Promise<Map<string, { size: number; mtimeMs: number }>>(id → 元信息,不含内容):让下游自行挑选要 loadSync(id, hint?) 的子集。
约束:同一 id 的 canonical 与 .fb.json spill 两个变体必须同进同出(都解析或都跳过),否则破坏现有 freshest-wins 对账语义。
消费方
billion-context SessionStore.boot() 会把 BILI_MAX_SESSIONS 的语义从"加载后截断内存"改造为真正的"加载预算"(#478 建议 4 的后半段):先 stat 预选,只解析预算内最新的记录,最旧的直接不解析(它们大概率也已被保留期 GC 清掉,两者互补)。
依赖顺序
按跨仓规则:acp-kernel 先发版并在 npm 上线,billion-context 再 bump 精确版本依赖并消费。
来源: ranxianglei/billion-context#478 分析 sessions 启动解析开销时发现
背景
billion-context#478 修复了 sessions 注册表存储的三重膨胀(叶块
blockContents逐字节双份、零 GC、每次启动两遍全量同步解析)。其中"启动解析时间随语料规模线性恶化"目前只能治一半:启动期 GC 把语料总量封顶(默认 1 GiB)之后,每次启动仍然要对全部存活文件做readFileSync+JSON.parse(kernelloadAll全量递归目录树,逐文件解析)。语料封顶在 GB 量级时,单次启动的同步解析仍是百毫秒~秒级开销,且随会话数线性增长。billion-context 侧无法绕过:选择性加载需要复刻 kernel 的 canonical/spill(
<name>.fb.json)savedAt 对账("freshest wins")逻辑,属于对 kernel 内部实现的脆弱复制,不可取。建议(二选一,均纯增量、默认行为不变)
loadAll(options?: { maxParseBytes?: number }):先只 readdir + stat(不读内容),按文件大小/mtime 从新到旧累加,超过预算的最旧文件跳过解析;或statAll(): Promise<Map<string, { size: number; mtimeMs: number }>>(id → 元信息,不含内容):让下游自行挑选要loadSync(id, hint?)的子集。约束:同一 id 的 canonical 与
.fb.jsonspill 两个变体必须同进同出(都解析或都跳过),否则破坏现有 freshest-wins 对账语义。消费方
billion-context
SessionStore.boot()会把BILI_MAX_SESSIONS的语义从"加载后截断内存"改造为真正的"加载预算"(#478 建议 4 的后半段):先 stat 预选,只解析预算内最新的记录,最旧的直接不解析(它们大概率也已被保留期 GC 清掉,两者互补)。依赖顺序
按跨仓规则:acp-kernel 先发版并在 npm 上线,billion-context 再 bump 精确版本依赖并消费。