Notist
On this page
  1. 架构优化实现与同批性能对照
  2. 结论与范围
  3. 实施边界
  4. 已实施
  5. 未实施,不能算作已完成
  6. 普通 CLI:单核同批中位数
  7. 已有输出完全一致,5 轮
  8. 强制完整替换,3 轮
  9. 无旧目录的首次构建,3 轮
  10. 波动与 CPU 时间
  11. 独立探针:收益位置与回退
  12. 内容树与调用
  13. 装配、检查与来源
  14. 路径预规划不能只看后移阶段
  15. 发布:no-op 的收益与真实替换的限制
  16. 优化后专用检查补充
  17. 四核补充
  18. 验收与复现

架构优化实现与同批性能对照

结论与范围

生产基线为 214de5fec5ea796a047024510566168e1fa81d08,优化侧是当前未提交补丁,不是另一个提交。普通 release 二进制在同一批次重新测量前后两侧,没有套用上一轮基线秒数。

  • 输出不变的完整重建:四种正文/模块负载加速 1.53–4.60 倍;XIV 加速 1.30 倍。

  • XIV 强制整站替换:1.01 倍,基本持平,不能据此声称稳定改善真实变更构建。

  • XIV 首次构建:1.11 倍;四核无变化重建为独立补充,不混入单核结果。

  • 主批次共 213 次完整成功构建,核对 3,080,809 个文件指纹,包括 3,080,057 份 HTML;各次最终输出均与原始完整清单一致。这些数字包含多轮重复验收,不是唯一页面数。

  • 另有 12 次优化后专用发布检查探针,核对 416,048 个文件指纹;它们仅用于定位新检查成本,不加入前后加速比。两批合计 225 次、3,496,857 个文件指纹,均保持输出一致。

  • 完整真实 XIV DB、页面枚举、所有正文、消费者、site.data 结构及依赖锁均未改变。SSG 输入请求及 Data 缓存预算的既有政策也未改变,不算作本次优化。

实施边界

已实施

  1. 树所有权:绑定/capture 只复制正在重建的节点边界,不先深拷贝马上替换的 children/pending;内部 present 消费已经拥有的森林;唯一持有的 Runtime Content 直接取得所有权。Analysis 保持不变,重复挂载继续隔离。

  2. 共享调用计划:CheckedProgram 与 InstanceRecord 使用 Arc/写时复制,调用共享 checked body;按扩展映射后的实际目标决定是否构造 Code Scope,原生调用避免无用的词法输入与 children 副本。

  3. 宿主批处理:共享 UTF-8 源码、批次配置解析与成功模块装配缓存;DocumentHandle 绑定 Vault 配置身份、路径、源码快照和 Environment,贯穿 SSG 求值及 HTML 绑定。模块图命中仍按原 DFS 顺序请求源码并计费。

  4. 有界检查计划复用:仅复用从空程序开始、无诊断且无 Data retention 的完整成功 Code 计划;每个 Context 基础最多 32 个计划/8192 个记录。安装模块或改写 Code 作用域时分离缓存,不合并多余实例绕过限制。

  5. 路径与产物:借用序列化站点扩展请求;消费扩展验证得到的 Route;生成输出先预留槽位、再一次填入字节;建立按输出路径和目录别名查询的链接索引,保持源身份优先。

  6. 发布与模板:暂存时去重创建父目录;实际有界比较全部旧输出字节及精确目录项,完全一致才跳过替换。至少 1024 页时,仅已准备的不可变模板工作可并行,最多 8 worker,按顺序合并产物与首个错误。

未实施,不能算作已完成

  • 参数槽位与实例 ID:求值器仍使用现有命名 Scope 和实例键,没有重写 IR 调用表示。

  • 产物 spool/staging sink:BuildOutput 仍拥有完整产物字节,未改变输出 API 与 IO 职责,也未测得内存下降。

  • 逐文件增量发布:当前只优化整站输出完全相同的情况;任意差异、额外目录项、symlink 或比较失败仍执行整站暂存、替换和同步清旧。

  • 全管线并行:输入、文档 hooks、分析、求值和发布保持既定顺序;只有模板任务并行。没有异步清理、移出计时的清旧或并行 Vault。

因此本轮完成了 P0、P1 和上述明确范围的 P2,不能概括为所有 P2 设想均已落地。

普通 CLI:单核同批中位数

单位为秒;CPU 固定为 8,文件系统缓存预热,每轮使用新的 CLI 进程。前后顺序交错,频率未锁定,不主张统计显著性。加速比为前侧中位数/后侧中位数。

已有输出完全一致,5 轮

完整负载

HTML 页

优化前

优化后

加速比

耗时减少

XIV

51,739

4.003808

3.087857

1.297×

22.9%

无模块正文

521

0.537173

0.274984

1.953×

48.8%

共享模块图

521

0.919440

0.238308

3.858×

74.1%

私有模块图

521

1.180939

0.769616

1.534×

34.8%

宽导出

521

1.641726

0.356587

4.604×

78.3%

强制完整替换,3 轮

计时外仅篡改本工具生成的旧输出 index.html,使发布必须替换;源输入不变。这是发布路径的控制实验,不是任意源文件修改的增量构建成本。暂存、替换和旧目录清理全部在计时内。

完整负载

优化前

优化后

加速比

XIV

3.822845

3.776232

1.012×

无模块正文

0.548684

0.288133

1.904×

共享模块图

0.920354

0.253182

3.635×

私有模块图

1.187984

0.819536

1.450×

宽导出

1.683181

0.375889

4.478×

无旧目录的首次构建,3 轮

只在此队列的计时外移除工具自身的输出;它不包含清旧工作,因此不与重建混算。

完整负载

优化前

优化后

加速比

XIV

3.663020

3.305422

1.108×

无模块正文

0.522393

0.270078

1.934×

共享模块图

0.903822

0.239237

3.778×

私有模块图

1.183650

0.772430

1.532×

宽导出

1.655242

0.356581

4.642×

波动与 CPU 时间

XIV 的无变化重建 wall 范围为前侧 3.962453–4.380826 s、后侧 3.011147–4.404894 s;后侧一个慢样本没有删除。强制替换范围为前侧 3.792995–4.030399 s、后侧 3.571661–3.780130 s。不同发布状态分时段运行,不能将各队列基线差异解释成某种发布模式固有成本。

无变化重建的 user/system 中位数如下;二者分别取中位数,不要求相加等于 wall 中位数。

完整负载

前 user

后 user

前 system

后 system

XIV

2.842782

2.702122

1.081328

0.375909

无模块正文

0.507117

0.253673

0.028889

0.017966

共享模块图

0.869984

0.211164

0.043838

0.026969

私有模块图

1.099564

0.682766

0.076751

0.087610

宽导出

1.577304

0.308455

0.055599

0.041867

完整的每种负载/模式 min、max、mean、median 及每次样本保留在 summary.json 和 samples.json。

独立探针:收益位置与回退

以下为独立插桩二进制、无变化重建三轮均值,单位 ms。不可与普通 CLI 秒数直接相减。前后细粒度插桩范围并不完全相同,只比较具有相同边界的阶段,不将合并优化包的收益拆成未经隔离验证的单项收益。

完整负载

分析前

分析后

求值前

求值后

XIV

783.150

752.328

130.990

77.966

无模块正文

142.000

145.553

316.615

71.725

共享模块图

234.929

55.831

591.276

109.780

私有模块图

484.526

479.731

613.113

142.704

宽导出

361.912

53.320

1162.869

189.338

内容树与调用

  • 无模块的 eval.bind_content 从 87.181 降至 26.725;eval.present 从 213.987 降至 44.565。纯正文也改善,不能把全部收益归于模块图缓存。

  • 共享图的 eval.present 从 506.562 降至 104.455;私有图从 524.353 降至 135.873;宽导出从 1018.319 降至 183.786。树所有权、checked body 共享和原生调用装配共同作用于这些区间,未分别作消融实验。

  • XIV 的底层 eval.run 是 38.913 → 43.856,并未改善;外层求值阶段的下降包含宿主环境查找/句柄路径变化。不能把 130.990 → 77.966 全称为解释器加速。

  • 无模块分析略增,私有模块分析基本不变;这些值和新增细粒度探针的开销一并保留,不声称所有阶段都变快。

装配、检查与来源

模块工作

共享图 前→后

私有图 前→后

宽导出 前→后

compile 调用

5192→89

5120→5120

3072→6

实际 compile 工作

18→18

5120→5120

6→6

bind 调用

5713→610

5641→5641

3593→527

实际 bind 工作

139→139

5632→5632

11→11

link/install 调用,各自

5192→89

5120→5120

3072→6

模块图 visit 调用

5712→5712

5632→5632

3072→3072

表内模块计数取每侧一个正式探针样本;实际工作数可受计算缓存保留影响,完整逐次计数仍在 samples.json。图装配复用减少重复进入已缓存计算、link 和 install,没有取消私有模块的真实编译,也没有跳过依赖源码请求。

配置解析从每页一次降为每批一次。共享图有 520 次检查计划查询、9 次成功计划登记,宽导出分别为 512/8;查询次数不是命中次数。私有图为 512/512,不能通过相同源码将不同模块身份混为共享计划。

保留缓存也有成本:私有图的 drop.vault 从 5.585 增至 36.553;共享图从 3.570 增至 13.829。没有测量 RSS 或分配量,不能由耗时推断内存改善。

路径预规划不能只看后移阶段

XIV 的逐页模板阶段为 519.645 → 345.077,但新实现把已知页面的路径冲突检测提前到了资源准备/预留阶段,后者为 0.751 → 140.733。连同 finish 的相关阶段合计为 520.400 → 491.278,而不是节省了全部 174.568 ms。优化后的 template.render_all 为 314.262 ms,包含当前页上下文设置;不能与旧实现只围住 engine.render 的子计时直接比较。

共享模板上下文为 215.839 → 209.858;site.data 仍转换一次,未改成懒加载、远程请求或新的消费者结构。

发布:no-op 的收益与真实替换的限制

无变化 XIV 探针:完整 publish 为 884.743 → 328.573 ms。旧侧写暂存 473.074、清旧 411.455;新侧完整字节/目录比较为 223.974,除此之外的发布检查成本也计入 publish,不能仅用 compare 代表全部发布成本。

强制替换 XIV 探针:publish 为 930.274 → 1052.572 ms;写暂存为 494.213 → 449.990,清旧为 435.859 → 479.590,优化侧还承担了 11.481 的失败 no-op 比较。目录去重确实删除了冗余系统调用,但没有消除逐文件写出与旧目录删除,也没有得到稳定的端到端替换加速。

独立 strace 控制如下;均包含 CLI 及扩展子进程,不能当作仅发布函数的精确调用数。trace wall 不参与性能结论。

syscall

前 same

后 same

前 replace

后 replace

mkdir

51749

0

51749

10

write

51748

4

51748

51748

unlinkat

51751

0

51751

51751

rename

2

0

2

2

read

3272

433369

3272

3295

所选 syscall 总计

315630

642243

315630

212208

无变化路径用实际读取换掉写出和清旧,系统调用总数反而增加;它不是零成本跳过。插桩调用边确认新增的 51,744 次有界后端读取来自 publish.compare;语言输入的 input.load → io.bounded_read 仍只有 1 次,不是语言 Data 读取增长。strace 下大量短 read 的额外拦截开销也使 no-op 的 trace wall 更慢,不能据此推翻普通二进制测量或用 trace 秒数计算加速。

优化后专用检查补充

为定位主批中 publish 剩余 Self,另建独立临时探针,未修改生产补丁或主批源快照。每组一次预热、三次正式测量,仍使用完整输入和逐文件验收;以下只描述优化侧该队列的三轮均值,单位 ms,不跨队列相减或用于加速比。

完整负载/状态

输出归属检查

相对路径校验

全字节比较

完整 publish

XIV/same

108.237

1.361

254.861

364.494

私有图/same

6.066

0.028

6.468

12.589

XIV/replace

106.084

1.149

11.405

1313.330

XIV 的额外百毫秒主要定位在输出归属检查区间,而非提前的相对路径循环;该区间包含 metadata、目录是否为空及现有 manifest 读取/解析,没有继续分离到底层调用或分配器。私有图的发布剩余成本、替换时的写出成本在两种插桩队列中也有明显差异,因此不拿本补充替换主批数值,不宣称已经解释或消除了全部回退。

补充证据保留在 publication-checks/manifest.json、samples.json、summary.json 和 integrity.json;入口为 tools/profile_publication_checks.py。最初一次补充脚本准备因重复锚点被安全拒绝,修正并通过语法测试后才开始计时,失败目录及日志保留。

四核补充

仅普通二进制、XIV 无变化重建,固定 CPU 8–11,独立预热后各三轮:前侧中位数 4.020495 s,后侧 2.891784 s,加速 1.390 倍。前侧范围为 3.913935–5.612445,后侧为 2.867420–2.913240;前侧一个慢样本保留。

优化后四核与优化后单核无变化队列中位数之比为 1.068,但两队列分时段运行,不是隔离模板并行开关的严格 A/B。不能将 1.390 倍全算为并行收益,也不报告线程局部探针的跨 worker 总计。

验收与复现

  • 工作区 all-features 串行测试:734 项通过。

  • 顶层 no-default-features 串行测试:370 项通过,与前项有重叠,不能相加当作独立测试数。

  • Python 工具测试:26 项通过。

  • 更新后的项目文档构建:49 页成功,输出位于 /tmp/opencode/notist-optimization-docs-20261103/,不计入性能样本。

  • 交互报告通过手机/桌面视口的页面数据与三种发布状态、探针负载切换检查。应用浏览器的截图 capture 超时,同时记录宿主 preload 文件缺失;未将其描述为截图验收成功。

  • Clippy 通过,仅保留 context.rs 的 bool::then/filter_map 和 profiling.rs 的 thread_local const 两条既有警告。

  • 新增或保留 Analysis 不变、重复挂载、扩展执行映射、空值/未选分支、累计预算、来源/相对 Path、NeedResources、句柄跨 Vault/配置/源码隔离、模块图请求额度、UTF-8/授权、预留槽位、并行模板顺序/首个错误、发布 stale/symlink 等回归。

  • Data 正向控制为 4 次语言读取、2 次实际解析;无变化输出比较不会冒充 Data 输入。

主批次 213 次由 140 次普通单核(含各自预热)、48 次探针(含预热)、8 次四核(含预热)、5 次 seed、3 次 Data 控制、4 次 strace 及 5 次预检组成。逐文件校验在每个子进程退出后、计时外进行;生产补丁、源快照、输入和二进制在批次前后验证一致。

复现入口为 tools/profile_optimizations.py,规则见 tools/OPTIMIZATION_PROFILE.md。交互图模板为 tools/optimization_profile_chart.html。原始证据位于 /tmp/opencode/notist-optimized-profile-20261103/,包含 manifest.json、optimization.patch、regression-tests.patch、sources、bin、samples.json、summary.json、strace.json、integrity.json、logs 和 inventories。

冻结的生产补丁 SHA-256 为 1998c01a1b9279bb4c00ca7ada382ede1ec39b82cf3f771dc15b0f8446651cd2,Cargo.lock 未变化。最初两次临时探针 release 构建分别因 RHS 误匹配 worker 局部变量、计时器遮蔽 links 迭代器失败,修正与日志均保留;它们发生在计时前,没有修改生产实现或删除慢样本。

最初未设置 NO_COLOR 的 CLI watcher 测试因终端转义失败;一次并行模块测试的 Arc 指针相等断言失败,隔离串行及最终完整串行均通过。没有修改这些既有断言掩盖失败。

本轮生产代码、回归、文档与工具仍未提交或推送;此前的历史分析和测量证据保留原貌。