news 2026/9/19 6:07:14

Yew 基准测试结果处理器 process-benchmark-results 原理与 CI 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Yew 基准测试结果处理器 process-benchmark-results 原理与 CI 实战

Yew 基准测试结果处理器 process-benchmark-results 原理与 CI 实战

【免费下载链接】yewRust / Wasm framework for creating reliable and efficient web applications项目地址: https://gitcode.com/gh_mirrors/ye/yew

导读

process-benchmark-results 是 Yew 仓库(Rust/Wasm 框架)中一个轻量但关键的工具:它将 js-framework-benchmark 与 CI 工作流,完整讲解数据格式差异、转换算法、命令行用法以及它在 Yew 性能监控流水线中的实际位置。读完本文,你将能够复现 Yew 的基准结果转换流程,并理解如何在自己的 Rust/Wasm 项目中接入持续基准测试。

一、工具定位:两套基准数据格式之间的桥梁

关联文档 tools/process-benchmark-results/README.md 用一句话概括了工具的全部使命:

Processes benchmark results —— From array of js-framework-benchmark —— Into array that works for the continuous-benchmark GitHub Action

也就是说,该工具解决的是数据格式适配问题,而非性能数据的采集或计算本身:

  • 上游输入:js-framework-benchmark 的webdriver-ts驱动浏览器跑分后,每个基准(benchmark)会输出独立的 JSON 结果文件;
  • 下游输出benchmark-action/github-action-benchmark@v1期望一个扁平的 JSON 数组,每个元素形如{ "name": ..., "unit": ..., "value": ... }

从仓库结构看,这个工具与 benchmark-struct(基于结构组件 API 的基准应用)、benchmark-hooks(基于函数组件/Hooks 的基准应用)以及 benchmark-core(虚拟 DOM 微基准)共同构成 Yew 的性能测试工具链,而 process-benchmark-results 处于这条链路的"出口"位置。

二、输入格式:js-framework-benchmark 的结果结构

Yew 的 CI 通过webdriver-ts运行基准,生成的原始文件位于js-framework-benchmark/webdriver-ts/results/*.json。为了把它们合并成一个数组,benchmark.yml 中使用了jq -s(slurp 模式):

jq -s . js-framework-benchmark/webdriver-ts/results/*.json \ | cargo run --manifest-path yew/Cargo.toml --release -p process-benchmark-results \ > artifacts/results.json

每个原始结果文件的 JSON 结构对应源码中的反序列化模型(main.rs 第 24-29 行):

struct JsKrauseBenchmarkResult<'r> { framework: &'r str, // 例如 "keyed/yew" benchmark: &'r str, // 例如 "01_run1k" r#type: &'r str, // 例如 "cpu" 或 "memory" values: HashMap<&'r str, ResultData>, // 键如 "total"/"DEFAULT",值为统计对象 } struct ResultData { median: Value, // 中位数,必须是数值 // 某些键可能缺失 }

值得注意的是ResultData只声明了median一个字段,注释明确写着 "some keys missing"——即原始数据中还存在minmaxmeanstd_devgeomean等其他统计量,但该工具只关心中位数(median),这正是它输出给图表 Action 的单一数值指标。这种"按需声明字段"的做法,正是 serde 默认允许缺失字段的宽容反序列化策略。

三、转换核心算法:median 提取与类型分流

transform_results 函数 实现了核心转换逻辑,其关键设计是按基准类型选择不同的 values 键

fn transform_results(mut result: JsKrauseBenchmarkResult<'_>) -> GhActionBenchmark { let key = if result.r#type == "cpu" { "total" // CPU 基准:取 "total" 键 } else { "DEFAULT" // 其他类型(如内存):取 "DEFAULT" 键 }; let values = result.values.remove(key).unwrap_or_else(|| { panic!( "Expect benchmark data to be present for type {}. Found keys: {:?}, expected {key:?}", result.r#type, result.values.keys().cloned().collect::<Vec<_>>(), ) }); assert!( values.median.is_number(), "expected a numerical benchmark value" ); GhActionBenchmark { name: format!("{} {}", result.framework, result.benchmark).replace('"', ""), unit: String::default(), value: values.median, } }

转换规则可总结为一张表:

输入字段处理逻辑输出字段
r#type == "cpu"values中取出键为total的统计对象取其median作为value
r#type为其他值(如 memory)values中取出键为DEFAULT的统计对象取其median作为value
framework+benchmark拼接为"{framework} {benchmark}",并移除字符串中的双引号"作为name
固定为空字符串unit
数值型中位数value(保持serde_json::Value原样)

这里有几个值得关注的工程细节:

  1. panic 式的防御:当某个基准类型对应的键不存在时,工具直接panic!并打印出当前实际存在的键集合,帮助 CI 日志快速定位"数据缺失"问题;assert!则保证了输出给图表的数据一定是数值,避免非法类型混入。
  2. remove而非getHashMap::remove在取出值的同时移除了该键,避免借用冲突,同时利用unwrap_or_else惰性构造错误信息。
  3. Value类型的贯穿使用medianserde_json::Value存储,输出时原样序列化,既不需要预先确定数值精度,也与下游 Action 对value的宽松要求兼容。
  4. 名称清洗.replace('"', "")防止框架名或基准名中的引号破坏下游 JSON 字段或图表标题。

四、输出格式:continuous-benchmark Action 的输入契约

转换后的数据结构定义在 main.rs 第 9-14 行:

#[derive(Serialize)] struct GhActionBenchmark { name: String, unit: String, value: Value, }

即一个GhActionBenchmark数组,例如:

[ { "name": "keyed/yew 01_run1k", "unit": "", "value": 123.456 }, { "name": "keyed/yew-hooks 02_replace1k", "unit": "", "value": 98.7 } ]

这个结构正是benchmark-action/github-action-benchmark@v1customSmallerIsBetter自定义工具模式所要求的输入:name用于图表与告警的标识,value为单一数值(此处为中位数),unit留空由 Action 侧自行决定展示单位。

五、在 Yew CI 流水线中的完整闭环

process-benchmark-results 只是"Benchmark"工作流的一环,理解它需要看它在整条流水线中的上下游(benchmark.yml):

  1. 基准构建:分别用wasm-pack build --release --target web构建 benchmark-struct 与 benchmark-hooks,输出到 js-framework-benchmark 仓库约定的bundled-dist/目录;
  2. 跑分:启动 js-framework-benchmark 服务器,用xvfb-run npm run bench -- --framework keyed/yew keyed/yew-hooks --runner playwright驱动浏览器执行基准,产出results/*.json
  3. 格式转换(本文主角)jq -s .合并所有结果文件后,通过cargo run --manifest-path yew/Cargo.toml --release -p process-benchmark-results执行转换,将输出重定向到artifacts/results.json;同时把完整事件信息写入artifacts/.PR_INFO(用于区分 master 与 PR 场景);
  4. 上传产物actions/upload-artifact@v7artifacts/上传为名为results的构建产物(保留 1 天)。

随后由 post-benchmark.yml 在"Benchmark"工作流完成后触发:下载results产物,交给benchmark-action/github-action-benchmark@v1处理——配置了tool: "customSmallerIsBetter"output-file-path: artifacts/results.jsonalert-threshold: "200%"(相对基线劣化超过 200% 时告警并 @ yewstack 团队),并在 master 提交上自动推送数据到gh-pages分支形成趋势图表,在 PR 场景则只生成对比评论(auto-pushsave-data-file根据.PR_INFO中是否存在 PR 编号动态决定)。

六、工具本身的工程属性

从 Cargo.toml 可以确认该工具的轻量定位:

  • 版本与语法version = "0.1.0"edition = "2024"rust-version继承工作区(根 Cargo.toml 声明为 1.85);
  • 依赖极少:仅anyhow(统一错误处理)、serde(含 derive,序列化/反序列化)、serde_json(JSON 解析与 Value 类型);
  • 无异步、无网络、无文件系统依赖:整个程序通过标准输入读取、标准输出写出,是一个纯粹的"管道过滤器"(pipe filter);
  • 工作区归属:根 Cargo.toml 将tools/*纳入 workspace members,因此 CI 中可用cargo run -p process-benchmark-results直接运行;同时 Makefile.toml 覆盖了doc-test任务(该工具不包含文档测试,输出 "No doctests run for process-benchmark-results"),说明它不参与文档测试流水线。

七、实战:在任意 Rust 项目中复现该转换

即便不依赖 Yew 的 CI 配置,你也可以独立复用这条转换链路。假设你的 js-framework-benchmark 结果位于results/目录,只需两步:

# 1. 合并多个基准结果文件为单个 JSON 数组 jq -s . results/*.json > merged.json # 2. 通过 stdin 喂给转换工具,从 stdout 取得 Action 兼容格式 cargo run --release -p process-benchmark-results < merged.json > results.json

注意在仓库内运行时应通过工作区定位(--manifest-path Cargo.toml),否则 cargo 无法解析process-benchmark-results包。转换完成后的results.json可直接作为benchmark-action/github-action-benchmark@v1customSmallerIsBetter数据源。

八、小结与延伸阅读

process-benchmark-results 用约 70 行 Rust 代码,精准完成了"js-framework-benchmark 原始结果 → continuous-benchmark Action 输入"的格式适配,其按type分流键名(total/DEFAULT)、取中位数、清洗名称并 panic 式校验的设计,保证了 Yew 持续基准图表数据的稳定与可诊断性。它是 Yew 将第三方基准框架与 GitHub Actions 图表能力衔接起来的关键一环。

若想进一步探索,可从以下仓库路径继续深入:

  • 转换逻辑完整源码:tools/process-benchmark-results/src/main.rs
  • 触发与运行该工具的工作流:.github/workflows/benchmark.yml
  • 消费转换结果并发布图表/告警的工作流:.github/workflows/post-benchmark.yml
  • 被基准的 Yew 应用:tools/benchmark-struct、tools/benchmark-hooks
  • SSR 基准的配套处理脚本(用于生成 PR 评论表格):ci/make_benchmark_ssr_cmt.py

【免费下载链接】yewRust / Wasm framework for creating reliable and efficient web applications项目地址: https://gitcode.com/gh_mirrors/ye/yew

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 6:07:10

纳米材料四大效应与工程应用:从催化剂到隐身材料

简介&#xff1a;纳米技术作为21世纪前沿科技&#xff0c;已深入材料、化工等多个领域。这份《纳米技术与纳米材料》资料面向材料、化学等相关专业学习者及对纳米科技感兴趣的读者&#xff0c;系统讲解纳米技术与纳米材料的核心概念&#xff0c;包括纳米尺度范围、纳米材料的定…

作者头像 李华
网站建设 2026/9/19 6:05:48

MathType嵌入Word完整教程:从安装到踩坑排查全记录

干了这么多年文档工程&#xff0c;我对MathType和Word这对搭档太熟了。你要是理工科出身&#xff0c;写论文、出报告、整教材&#xff0c;十有八九躲不开公式排版。Word自带的公式编辑器其实够用&#xff0c;但真到了要写长文档、公式带编号、批量改格式的时候&#xff0c;Math…

作者头像 李华
网站建设 2026/9/19 6:04:24

PFC6.0柔性三轴体变监测工具开发与应用

1. 项目背景与核心价值最近在岩土工程数值模拟领域&#xff0c;PFC6.0&#xff08;Particle Flow Code&#xff09;作为一款基于离散元方法的专业软件&#xff0c;其强大的颗粒流分析能力一直备受工程师和研究人员的青睐。而其中的"柔性三轴"模块更是模拟土体力学行为…

作者头像 李华
网站建设 2026/9/19 6:04:23

401 invalid_api_key?TaoToken + Cline 这样验证模型 ID

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 6:00:57

数据中台维度建模实战:核心挑战与优化策略

1. 数据中台建模的核心挑战与价值数据中台建设过程中最让人头疼的就是如何把分散在各业务系统的数据整合成可复用的资产。我经历过三个不同行业的数据中台项目&#xff0c;发现70%的实施难点都集中在数据建模环节。传统的数据仓库建模方法在面对互联网时代的快速业务变化时&…

作者头像 李华