report 设计
设计目标
基准测试报告必须能从审计记录复现,并且可以安全地分享。report 是一个纯投影:从 JSONL 事件流到 Plot IR(ir_model),再从 Plot IR 到 JSON、SVG 和 HTML。它从不判定什么更快;它展示流中包含的内容,并且绝不让一次无效的测量看起来像有效的。
数学背景
投影
设流是一个事件序列。用 表示 valid 为真且 batch_sink 为 "kept" 的观测,用 表示状态为 invalid 或 infrastructure_failure 的验证所对应的键 的集合。绘制的点为
按流中的顺序排列。该投影对于不利于某个点的证据是单调的:增加一个失败的验证只会移除点,增加一个无效观测不会添加任何点。
坐标
一张图表占据 视框中的矩形 。若按首次出现顺序有 个不同的 x 类别,则类别 位于
设 和 为 y 的极值。y 的范围会加上留白,
空图表则为 。在每种情况下都有 ,因此线性映射
是良定义的,并且对每个绘制的值都有 ,这使每个点都严格位于绘图区域内部。热力图单元格使用不透明度 ,因此它严格介于 和 之间:没有单元格是不可见的,也没有单元格是完全饱和的。
网格线绘制在 处(),刻度值为 ,四舍五入到三位小数。若有 个类别,则每隔 个类别以及在最后一个类别处绘制标签,因此最多显示十一个标签。
设计决策
纯投影,副作用在外
问题。 渲染器改动后需要重新生成报告,并在评审中进行比较。选择。 document_from_jsonl、plot_json、plot_svg 和 html 接收值并返回字符串;文件 IO、标准流和打开浏览器都位于 cli 中。理由。 同一份 JSONL 在每个目标上都给出相同的字节,测试不需要文件系统,HTML 也可以在更大的应用中生成。
失败会移除系列,并保持可见
问题。 一个返回错误结果的快速实现看起来会像是赢家。选择。 失败的验证会移除该实现在该用例和数据集上的点,并添加一行不匹配记录;最小化后的失败会添加一行带重放命令的反例。理由。 差分部分位于图表上方,因此读者能看到某个系列缺失的原因。
原始点加均值线
问题。 摘要掩盖分布,原始点云掩盖趋势。选择。 每个观测都带提示地绘制出来,对于线型图表,各类别的均值把类别连接起来。理由。 所绘各点的均值正是肉眼已经在估计的重心;稳健统计和决策属于 stats,可以作为更多图表添加。这条线是参考线,而不是报告为之担保的估计。
分类 x 轴
问题。 规模可能是整数、形状、布局或名称。选择。 PlotPoint.x 是字符串,坐标轴按首次出现的顺序均匀放置类别。理由。 数值坐标轴需要为每种规模定义一个类型。代价是间距不反映大小,而且 Pareto 视图只是分类散点图,而不是二维前沿。
转义顺序
文本转义按此顺序替换 &、<、>、" 和 '。& 必须排在最前:若在 < 之后再替换它,生成的 < 就会变成 &lt;。由于之后的每次替换引入的 & 都已经是某个实体的一部分,结果恰好能解码回输入一次。同一个函数既转义元素文本,也转义属性值。
自包含的输出
HTML 内嵌其 CSS 和内联 SVG,不加载任何字体、脚本或图像,并声明 color-scheme: light。它可以作为附件添加到 issue 中,或与 JSONL 一起归档,十年后渲染效果依然相同。
版本关卡
artifact_version 为 mmka_1 以外字符串的行会被拒绝,并报告其行号。没有该字段的行会被接受,因此手写的测试数据和较早的流仍然可读;非字符串的版本是错误。JSON 输出携带 schema_version mmks_1。
正确性与不变量
- 确定性。 每个函数都是纯函数;相等的输入给出相等的字符串。
- 排除。 没有点来自无效的、被丢弃的或被失败验证覆盖的观测( 的定义)。
- 包含。 每个点都严格位于绘图区域内部,每个热力图不透明度都位于 中(推导见上文)。
- 转义。 所有来自事件、标题、单位和系列名称的文本在进入 SVG 或 HTML 之前都会经过转义函数。
- 复杂度。 解析与流的大小成线性关系,只是每个点都要与失败键列表比对,代价为 。渲染含 个点、 个类别和 个系列的图表需要 ,因为每个单元格都会重新计算线的均值。
被否决的方案
- JavaScript 图表库。 它需要脚本或 CDN,并会使输出依赖浏览器运行时。
- 只渲染摘要。 会掩盖双峰性和离群值。
- 数值 x 轴。 需要为每个用例定义规模类型;已推迟。
- 把失败的实现视为零时间或无穷时间。 在计时坐标轴上,两者都是误导性的值。
边界
- JSONL 投影只构建一张
Scaling图表。当调用者在 Plot IR 中构造其他种类的图表时它们也会被渲染,但目前还没有任何代码从事件中派生它们。 - 探索性阶段和验证性阶段的观测绘制在一起,x 值是数据集索引,而不是规模。
- 目标由调用者传入;它不是从流中读取的。
- 这里不计算统计量、决策或环境比较。
- 样式、颜色和布局不属于兼容性承诺;
mmks_1JSON 结构才是。