2026-11-02 模块密集型完整站点:comemo 评估
为什么另做这个例子
生产 XIV DB 没有 notc 导入,模块编译执行为零,无法说明编译缓存的效果。本轮另行构造完整组件化商品站点,包含实际的多层导入、函数调用、HTML 表格、目录、导航和 Tera 模板;不把这个虚构负载的加速比套到生产 XIV DB 上。
没有修改消费者、依赖锁、引擎实现或生产限制。只新增 profiling-feature-gated example、fixture/测量工具及报告;原有语言能力改动保留。
结论
521 页共享组件站点,无缓存 → 两处缓存:
首轮完整组装 2233.40 → 2039.62 ms,减少 8.7%。
同进程新 Vault 重建 2203.33 → 2044.80 ms,减少 7.2%。
进程峰值 RSS 225.8 → 138.1 MiB,减少 38.8%,口径覆盖整个编辑序列。
首轮模块编译实际执行 5192 → 18,绑定实际执行 5713 → 139;不变重建两者都为 0。
缓存并不只在第二轮生效。 首轮的不同页面已经在复用相同模块,所以冷/热组装时间本身接近,并不表示缓存无效;应当在相同阶段比较 off、compile、both。
整站主要收益来自编译缓存。绑定缓存确实减少了真实绑定工作,但相对于仅编译缓存,额外整站耗时差异小且范围重叠,本轮不能声称稳定的额外整站提速。
首轮编译阶段约 141.86 → 2.12 ms,绑定约 19.66 → 3.70 ms。这些阶段自身大幅变快,但原本只占约 7% 的总时间,页面解析、实例检查、求值、资源读取和模板等并未被缓存,因此整站不是几倍加速。零实际执行也不等于零开销:热轮 compile/bind 仍约 1.45/3.27 ms,用于查询、键处理和依赖验证等。
测试例
shared:512 详情 + 8 个目录页 + 首页 = 521 HTML。每件物品的 13 个字段由真实 notc 组件渲染,包含变长标题、中文、整数、布尔和 HTML 敏感字符。库分为字段标签、格式化、元数据、版本、徽标、通配重导出 facade、详情组件、8 个分组包装模块及目录组件。正常访问 18 个不同模块,重定向时额外访问另一版本模块。
private:64 详情 + 目录 + 首页 = 66 HTML。每个详情的模块图源身份完全独立,首轮不能跨页复用;后续重建仍能复用同一页的模块。目录和首页不导入模块。
no-imports:与 shared 同规模的 521 页,数据直接表示为普通字面量 Markup,没有 notc 导入,用作负对照。
所有导入形态都实际出现:命名空间、成员选择、通配、传递重导出。没有用大量未调用的函数来人为撑大编译成本。不同负载之间不比较绝对耗时,只在各自负载内比较模式。
共享站点完整编辑序列
每个模式三个独立新进程,同一二进制切换 profiling-only 模式;每个场景新建 Vault,但保留进程级计算缓存。下表为三次中位数,“编译/绑定”为实际工作执行次数。
场景 | off ms | compile ms | both ms | off 编译/绑定 | compile 编译/绑定 | both 编译/绑定 |
|---|---|---|---|---|---|---|
首轮 cold | 2233.40 | 2048.66 | 2039.62 | 5192/5713 | 18/5713 | 18/139 |
不变重建 warm | 2203.33 | 2035.88 | 2044.80 | 5192/5713 | 0/5713 | 0/0 |
同长度函数体修改 body | 2213.23 | 2035.26 | 2022.85 | 5192/5713 | 1/5713 | 1/0 |
追加未使用导出 export | 2215.17 | 2032.98 | 2023.50 | 5192/5713 | 1/5713 | 1/3 |
只改第 0 组 local | 2213.81 | 2044.11 | 2034.04 | 5192/5713 | 1/5713 | 1/0 |
重导出目标切换 redirect | 2312.01 | 2135.08 | 2118.84 | 5712/6233 | 2/6233 | 2/4 |
删除必需导出 missing | 46.73 | 46.54 | 46.26 | 9/9 | 1/9 | 1/3 |
重复错误 missing-warm | 46.51 | 46.45 | 46.44 | 9/9 | 0/9 | 0/0 |
恢复正确源码 repaired | 2210.90 | 2059.60 | 2028.20 | 5192/5713 | 0/5713 | 0/0 |
显式淘汰后 evicted | 2202.68 | 2042.09 | 2032.49 | 5192/5713 | 18/5713 | 18/139 |
missing 是预期失败,不能把其约 46 ms 当成成功整站构建。恢复源码后可复用之前有效的缓存条目,输出必须正确;显式清空后,实际工作恢复至首轮的不同模块/绑定数量,而不是每页都重做。
首轮耗时范围:off 2225.32–2241.60、compile 2043.50–2104.01、both 2013.58–2040.15 ms。不变重建范围:off 2200.52–2215.34、compile 2016.96–2041.88、both 2013.10–2051.67 ms。
峰值 RSS:off 225.8 MiB,compile 154.7 MiB,both 138.1 MiB。不是每个场景独立的峰值。
对照组
负载/场景 | off ms | compile ms | both ms | both 实际编译/绑定 |
|---|---|---|---|---|
私有模块图,首轮 | 240.67 | 236.16 | 238.52 | 640/704 |
私有模块图,重建 | 234.28 | 216.46 | 215.01 | 0/0 |
无导入,首轮 | 761.54 | 766.85 | 762.53 | 0/0 |
无导入,重建 | 747.59 | 767.55 | 745.53 | 0/0 |
私有模块图三种模式首轮均实际编译 640 次,没有明显首轮收益;不变重建才减少约 8.2%。无导入时 compile_work 一直为零,整站时间没有稳定收益,与生产 XIV DB 的观察一致。
正确性与测量边界
共 27 个工作进程、126 次组装尝试:108 次成功完整组装,18 次预期缺失导出失败。另做 8 详情/3 私有详情的小规模端到端验收。
全部成功输出逐文件 SHA-256 在相应模式/重复之间相同,逐页校验所有 13 字段、完整物品集、目录行和本地链接。总计验证 48,078 HTML,没有只抽查个别页面。
正文修改必须把 stamp-A 更新为 B;新增未使用导出不改变 HTML;local 必须仅改变第 0 组的 64 个详情;redirect 的公共版本为 C,显式徽标导入仍为 B;重复错误诊断一致;修复及淘汰后产物与正确正文版本完全一致。
不仅看秒数:工具断言实际 compile/bind 工作计数,验证单文件修改、窄依赖失效、错误缓存和淘汰没有悄悄跳过工作。
CPU 8,同一个 release 二进制,debug=0、incremental=0、jobs=2;各模式顺序轮转,三次重复让每种模式在每个位置各出现一次。频率未锁定。编译及 HTML 验证不与正式测量并发。
fixture 预先装入不可变 MemoryResources,编辑快照制作不计时。每轮仍走正常 Vault 资源读取、授权、版本检查及计费;统一显式 requests=1,000,000,不改变生产默认值。
组装计时包含批次缓存维护、Vault 新建、全量 SSG 分析/求值/HTML/模板/内存产物组装和 Vault 释放;不含 fixture 生成、Rust 编译、验证副本写盘、输出对象释放、HTML 解析及 SHA-256。不是 CLI 发布事务或磁盘 benchmark,也不是缓存页面/实例检查/求值/模板。
RSS 为 Linux wait4 进程高水位,不是进程树同时内存总和。模块阶段为包含式,compile_work 属于 compile,bind 属于 link,不可全部累加。
工具 5 项专项回归、此前 profile 工具 6 项回归通过;现有模块缓存/淘汰 7 项 Rust 回归通过;新 example 的 rustfmt 检查通过。
复现
工具说明:tools/MODULE_SITE_PROFILE.md。
PYTHONDONTWRITEBYTECODE=1
本轮结果目录:/tmp/opencode/comemo-module-site-20261102。包含 fixture 逐文件指纹、release 二进制及 SHA-256、原始计时 JSON、每次 stdout/stderr、所有输出副本、summary.json 和 report.md。源代码为当前未提交工作区;没有把仅针对虚构新例子的数字写回历史生产站点序列。