状态:待 review,尚未实施。
把 bench 从 CI 里整个删掉,改成一条本地可重复的命令产出数据;当前只承诺
Linux,其他平台在文档里明确标 (未测试);标准数据集固定为 3 轮。
删除的理由必须是事实,不是偏好。当前 bench/matrix.json 的账:
| 格子数 | 10 |
| 外部引擎臂总数 | 32 |
被 allow_failed 豁免的 |
12(37%) |
| 其中 xmake | 在测 4 / 豁免 6 —— 豁免多于在测 |
| 其中 cmake | 在测 5 / 豁免 5 |
也就是说:一个自称「跨引擎对比」的矩阵,有三分之一的对比臂从未产出过数字,而 job 是绿的。这不是"还没修完",这是这个东西在 CI 上跑的形态本身就不成立:
- 共享 runner 上测的是 runner,不是引擎。 两核机器、邻居噪声、镜像随时更新。 同一份代码在 runner 上 cold 是 243s,在开发机上是 79s —— 三倍差距不来自 mcpp。
- 外部工具的缺口不是 mcpp 的缺陷,却由 mcpp 的 CI 承担。 xmake 编不了
libc++ 的
import std、bazel 的 MSVC 依赖扫描器坏掉、rules_cc 不支持 Windows PIC —— 每一个都要在 mcpp 的矩阵里挂一条豁免,而豁免越多,绿色越没意义。 - 一次矩阵约两小时,而它回答的问题("性能有没有退")在 PR 粒度上并不需要每次回答。 真正需要它的时刻是发版前和做完一次优化后,那两个时刻都有人在场。
保留 CI 里的哪一部分:tests/e2e/230_bench_harness.sh(套件自身能构建、能跑出一份
合法报告)继续留在 e2e 里。删掉的是跑真实工作负载的那个矩阵,不是套件的自测。
删除
.github/workflows/bench.yml整个文件
保留,但改变角色
bench/matrix.json—— 从「CI 跑哪些格子」变成「标准数据集的定义」。 这一点很关键:清单仍然只有一份,只是读它的人从 workflow 变成了本地脚本。bench/src/**—— harness 本身不动。bench/results/**—— 数据仍然入库。
新增
bench/run-standard.sh(名字待定)—— 读matrix.json,跑当前平台的格子, 3 轮,输出到bench/results/<date>-<os>-<arch>/。一条命令,不带参数也能跑。
必须同步改的守卫(否则删完 e2e 直接红)
tests/e2e/233_bench_matrix.sh现在有 5 处读.github/workflows/bench.yml: 第 48/53 行(存在性)、427(workflow 读 matrix.json)、438(--runs与 dispatch 默认值)、475/480(runner 镜像不得内联)。这些检查的对象要从 workflow 换成bench/run-standard.sh,判据不变:清单只有一份、脚本读它而不重复它。tests/e2e/232_workflow_syntax.sh会少一个文件,无需改。
| 平台 | 承诺 | README 写法 |
|---|---|---|
| Linux x86_64 | 本次真实跑出 | 完整数据 |
| macOS | 不跑 | (未测试) |
| Windows | 不跑 | (未测试) |
(未测试) 不是 (不支持)。差别要在文档里写明:没有数据 ≠ 不能用,而
"曾经有过一版数据、但那版数据是在有缺陷的 harness 上取的"更要写明 —— 见 §5。
从现有 10 格里取 Linux 的 6 格,并去掉所有需要豁免的外部臂:
| 工作负载 | 编译器 | 引擎 | 说明 |
|---|---|---|---|
fixture |
gcc | mcpp, cmake, xmake | 三引擎,唯一能控制 variant 轴的地方 |
fixture |
clang | mcpp, cmake, xmake, bazel | 四引擎 |
mcpp-2026.8.11.3 |
gcc | mcpp, xmake | cmake 有未定案缺口 → 不列 |
mcpp-2026.8.11.3 |
clang | mcpp, cmake | xmake 有已复现缺口 → 不列 |
xlings-2026.8.11.2 |
gcc | mcpp | 两个外部臂都有缺口 |
xlings-2026.8.13.1 |
gcc | mcpp | 同上,与上一行成对(两种代码风格) |
原则:标准集里不出现豁免。 一条臂要么在测,要么不在这张表里 —— 它的缺口写进 §5 的「已知缺口」清单,附证据。这样"标准数据"里的每一个数字都是真的跑出来的, 不需要读者去分辨哪些是豁免掉的。
3 轮(--runs 3),取中位数,同时记录 min/max。
理由:n=1 没有离散度,而现有 README 每张表都标 n=1 并附带"不要比较个位数字"的
警告 —— 那个警告本身就说明 n=1 不够。3 轮 × 6 格 × 5 场景在开发机上约 40–60 分钟,
是一个人可以在一次会话里跑完的量。
沿用现有六个:cold / noop / touch-hub / touch-leaf / edit-body /
edit-comment。真实工程略去 touch-leaf(现有 note 已说明:真实的树里没有
"没人 import 且足够稳定可以点名"的单元)。
- 工具链载荷齐备:
xim-x-gcc/16.1.0、xim-x-llvm/22.1.8、xim-x-binutils、xim-x-glibc - 外部工具按
matrix.json的tools钉住:cmake 4.0.2 / xmake 3.1.0 / bazel 9.2.0 - 子模块已 checkout(三个 pinned 工作负载)
- 依赖包已解包(
mcpplibs.cmdline等)—— 现在 cmake 臂会 FATAL_ERROR,好过静默少编
# 1. 构建被测的 mcpp 与 harness
mcpp build --release
cd bench && mcpp build --release && cd ..
# 2. 拉取钉住的工作负载
git submodule update --init
# 3. 跑标准集(一条命令,内部按 matrix.json 展开 Linux 的格子)
bash bench/run-standard.sh
# → bench/results/2026-08-14-linux-x86_64/*.json + report.md每份报告已经带 host(CPU 型号、核数、内存、是否异构)。再补两件:
- 被测 mcpp 的版本与 commit —— 现在只记版本号,同一版本可以有不同 commit
- 跑完的时间戳与总耗时 —— 用于判断两次数据是否可比
- 退出码 0
failed为 0、waived为 0(标准集里不该有豁免)- 每个
cold都通过既有的两条不变量(vs 自身 noop ≥2×、vs 同侪 ≤20×) - 三轮的 min/max 跨度不超过中位数的 ±20% —— 超了就是机器有噪声,数据不发布
现在的 bench/README.md 是一份实验记录:900 行,大量"这里曾经错在哪"。
那些内容有价值,但它不是一个人第一次想跑 bench 时该读到的东西。
改成三层:
bench/README.md
├─ 一、怎么跑(前 40 行,可以照抄的命令)
├─ 二、标准数据(Linux 表格 + 其他平台标 (未测试))
└─ 三、方法与已知缺口(现有内容,往后放)
「怎么跑」必须是可重复的:给出完整命令序列、预期耗时、以及"跑完怎么判断这份 数据能不能用"(§4.4 的四条)。现在的 README 里这些信息散在 §6 和 §10。
已知缺口单独成节,每条写:现象、归属(我们的 / 上游的)、复现方式、试过什么。 当前应当列入:
| 缺口 | 归属 | 证据 |
|---|---|---|
xmake + libc++ 编不了真实工程的 import std |
上游 | 本机复现,--sdk 与两种工具链都试过 |
cmake 在 CI runner 上 __CMAKE::CXX23 不可用 |
未定 | 外部可查项全部与能跑通的机器一致 |
cmake 读 xlings 依赖包时 manifest has no sources |
我们的 | 本机 rc=0,runner 上某个 compat-x-* 缺 sources;具体包名待补 |
| bazel MSVC 依赖扫描器 | 上游 rules_cc | Windows 专有 |
中文版同步,并保留"以英文版为准"的声明。
bench/results/ 里已有 30 个 JSON。不删,但要在 README 里分层:
- 标准数据:本次 Linux 实测那一份(3 轮),README 的表格只引用它
- 历史数据:其余的,标注日期与当时的 harness 状态
bmi_schedule=on 那一列的旧数据是在 §8b 缺陷修复之前取的,
touch-hub/edit-comment 两格量的工作比构建欠下的少(已在 README §8b 记录)。
本次重测应当把这一列一并重取,让标准表里不再混有修复前的数字。
| 取舍 | 得 | 失 |
|---|---|---|
| CI 不再跑 bench | 省两小时/次;不再用绿色掩盖 12 条豁免 | 性能回归不再自动发现 |
| 只承诺 Linux | 数字都是真的 | 跨平台差异无数据 |
| 标准集不含豁免臂 | 表里每个数字都真跑过 | 表变小(32 臂 → 约 14 臂) |
最大的失是第一条。缓解:把「发版前跑一次标准集」写进发布流程文档
(release-publish-pipeline 那条);优化类 PR 在描述里附本地数据。
不做的事:不搞"CI 里跑一个缩水版 bench"。缩水版会重新引入"绿色代表什么" 的模糊地带 —— 这正是要删掉它的原因。
bench/run-standard.sh这个名字与位置,是否放在bench/下- 标准集的格子清单(§3.2)是否合适 —— 尤其是否要保留
xlings的两格 (它们只有 mcpp 一条臂,是"两种代码风格对比"而非"引擎对比") - 3 轮是否够;要不要对
cold单独加轮次 bench/matrix.json是否继续承载"标准集定义",还是另起一个更小的文件- §6 的历史数据:保留还是清理到只剩标准集