关于 codspeed-setup-harness
codspeed-setup-harness 是一项指导为项目建立 CodSpeed 性能基准的技能,面向需要测量和跟踪性能的工程师。它按语言和工作负载选择基准框架与测量模式,并提供编写及验证基准的流程。
主要功能
- 01分析项目语言、构建系统与热点
- 02按语言选择 CodSpeed 基准框架
- 03配置通用 exec 基准方案
- 04选择模拟、墙钟或内存模式
- 05编写、运行并检查基准
适用场景
- 01为 Rust、Python 或 Node.js 项目配置基准
- 02测量 Go 项目的执行时间
- 03无需改代码测量整个程序
- 04检查基准代表性并验证运行结果
MCP 相关
文档提及使用 `query_flamegraph` MCP 工具查看火焰图;未说明该技能提供 MCP 服务或连接管理功能。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ codspeedhq/ codspeed --skill codspeed-setup-harness安装后在 Claude Code 中输入/codspeed-setup-harness确认已加载。
详细介绍
设置基准测试工具链
你是一名性能工程师,负责为项目设置基准测试并集成 CodSpeed。你的目标是创建有用且具有代表性的基准测试,并完成接入,让 CodSpeed 能够测量和跟踪性能。
第 1 步:分析项目
编写任何基准测试代码之前,先了解项目的情况:
-
检测语言和构建系统:查看项目结构、软件包文件(
Cargo.toml、package.json、pyproject.toml、go.mod、CMakeLists.txt)以及源文件。 -
识别现有基准测试:检查基准测试文件、
codspeed.yml,以及提及 CodSpeed 或基准测试的 CI 工作流。 -
识别热点路径:查看代码库,了解哪些代码对性能至关重要。公共 API 函数、数据处理流水线、I/O 密集型操作和算法代码都是不错的候选项。
-
检查 CodSpeed 身份验证:确保已运行
codspeed auth login。
第 2 步:选择合适的方案
根据语言和用户想要进行基准测试的内容,选择合适的工具链:
特定语言的工具链(有条件时推荐)
这些工具链与 CodSpeed 深度集成,可提供各基准测试的火焰图、精细对比,以及模拟模式支持。
| 语言 | 框架 | 设置方法 |
|---|---|---|
| Rust | divan(推荐)、criterion、bencher | 使用 cargo add --rename 将 codspeed-<framework>-compat 添加为依赖项 |
| Python | pytest-benchmark | 安装 pytest-codspeed,使用 @pytest.benchmark 或 benchmark fixture |
| Node.js | vitest(推荐)、tinybench v5、benchmark.js | 安装 @codspeed/<framework>-plugin,在 vitest/test 配置中进行配置 |
| Go | go test -bench | 无需安装软件包 — CodSpeed 可直接检测 go test -bench |
| C/C++ | Google Benchmark | 使用 CMake 构建,CodSpeed 通过 valgrind-codspeed 进行检测 |
Exec 工具链(通用)
适用于任何语言,或需要对整个程序(而非单个函数)进行基准测试的情况:
- 使用
codspeed exec -m <mode> -- <command>运行一次性基准测试 - 或创建
codspeed.yml,定义可重复使用的基准测试配置
Exec 工具链无需更改代码 — 它会在外部检测二进制文件。以下情况尤其适用:
- 没有专用 CodSpeed 集成的语言
- 端到端基准测试(完整程序执行)
- 只想跟踪某条命令的性能时快速设置
选择模拟模式还是实时时间模式
- 模拟模式(Rust、Python、Node.js、C/C++ 的默认模式):确定性 CPU 模拟,方差小于 1%,自动生成火焰图。最适合 CPU 密集型代码。不测量系统调用或 I/O。
- 实时时间模式(Go 的默认模式):测量真实执行时间,包括 I/O、线程和系统调用。最适合 I/O 密集型或多线程代码。需要保持硬件一致(在 CI 中使用 CodSpeed Macro Runners)。
- 内存模式:跟踪堆分配。最适合减少内存用量。支持使用 libc/jemalloc/mimalloc 的 Rust、C/C++。
第 3 步:设置工具链
使用 divan 的 Rust(推荐)
- 添加依赖项:
cargo add divan
cargo add codspeed-divan-compat --rename divan --dev
- 在
benches/中创建基准测试文件:
// benches/my_bench.rs
use divan;
fn main() {
divan::main();
}
#[divan::bench]
fn bench_my_function() {
// Call the function you want to benchmark
// Use divan::black_box() to prevent compiler optimization
divan::black_box(my_crate::my_function());
}
- 在
Cargo.toml中添加:
[[bench]]
name = "my_bench"
harness = false
- 构建并运行:
cargo codspeed build -m simulation --bench my_bench
codspeed run -m simulation -- cargo codspeed run --bench my_bench
使用 criterion 的 Rust
- 添加依赖项:
cargo add criterion --dev
cargo add codspeed-criterion-compat --rename criterion --dev
- 在
benches/中创建基准测试:
use criterion::{criterion_group, criterion_main, Criterion};
fn bench_my_function(c: &mut Criterion) {
c.bench_function("my_function", |b| {
b.iter(|| my_crate::my_function())
});
}
criterion_group!(benches, bench_my_function);
criterion_main!(benches);
- 在
Cargo.toml中添加配置,然后按照 divan 的方式构建和运行。
使用 pytest-codspeed 的 Python
- 安装:
pip install pytest-codspeed
# or
uv add --dev pytest-codspeed
- 创建基准测试:
# tests/test_benchmarks.py
import pytest
def test_my_function(benchmark):
result = benchmark(my_module.my_function, arg1, arg2)
# You can still assert on the result
assert result is not None
# Or using the pedantic API for setup/teardown:
def test_with_setup(benchmark):
data = prepare_data()
benchmark.pedantic(my_module.process, args=(data,), rounds=100)
- 运行:
codspeed run -m simulation -- pytest --codspeed
Node.js 与 vitest(推荐)
- 安装:
npm install -D @codspeed/vitest-plugin
# or
pnpm add -D @codspeed/vitest-plugin
- 配置 vitest(
vitest.config.ts):
import { defineConfig } from "vitest/config";
import codspeed from "@codspeed/vitest-plugin";
export default defineConfig({
plugins: [codspeed()],
});
- 创建基准测试文件:
// bench/my.bench.ts
import { bench, describe } from "vitest";
describe("my module", () => {
bench("my function", () => {
myFunction();
});
});
- 运行:
codspeed run -m simulation -- npx vitest bench
Go
无需安装任何软件包 — CodSpeed 可直接检测 go test -bench。
- 创建基准测试:
// my_test.go
func BenchmarkMyFunction(b *testing.B) {
for i := 0; i < b.N; i++ {
MyFunction()
}
}
- 运行(Go 默认使用 walltime):
codspeed run -m walltime -- go test -bench . ./...
使用 Google Benchmark 的 C/C++
-
安装 Google Benchmark(通过 CMake FetchContent 或系统软件包)
-
创建基准测试:
#include <benchmark/benchmark.h>
static void BM_MyFunction(benchmark::State& state) {
for (auto _ : state) {
MyFunction();
}
}
BENCHMARK(BM_MyFunction);
BENCHMARK_MAIN();
- 使用 CodSpeed 构建并运行:
cmake -B build && cmake --build build
codspeed run -m simulation -- ./build/my_benchmark
Exec 测试框架(任意语言)
无需更改代码,即可对整个程序进行基准测试:
- 创建
codspeed.yml:
$schema: https://raw.githubusercontent.com/CodSpeedHQ/codspeed/refs/heads/main/schemas/codspeed.schema.json
options:
warmup-time: "1s"
max-time: 5s
benchmarks:
- name: "My program - small input"
exec: ./my_binary --input small.txt
- name: "My program - large input"
exec: ./my_binary --input large.txt
options:
max-time: 30s
- 运行:
codspeed run -m walltime
也可以一次性运行:
codspeed exec -m walltime -- ./my_binary --input data.txt
第 4 步:编写高质量的基准测试
高质量的基准测试应具有代表性、彼此隔离且稳定。请参考以下建议:
-
对真实工作负载进行基准测试:使用真实的输入数据和规模。对 10 个元素进行排序的基准测试,无法说明对 1,000 万个元素排序的性能。
-
避免将准备工作纳入基准测试:使用框架的准备/清理机制,将初始化排除在测量之外。
-
防止死代码消除:使用
black_box()(Rust)、benchmark::DoNotOptimize(C++)或Blackhole.consume(JMH),避免编译器优化掉未使用的结果。 -
覆盖关键路径:对用户最关心的函数进行基准测试 — 也就是频繁调用或处于热路径上的函数。
-
测试多种场景:测试不同的输入规模、数据分布和边界情况。性能特征往往会随着规模变化。
-
保持基准测试快速:单项基准测试应在几毫秒到几秒内完成。CodSpeed 会处理预热和重复运行 — 你只需提供单次迭代。
第 5 步:验证并运行
设置完成后:
- 在本地运行基准测试,确认其正常工作:
# For language-specific harnesses
cargo codspeed build -m simulation && codspeed run -m simulation -- cargo codspeed run
# or
codspeed run -m simulation -- pytest --codspeed
# or
codspeed run -m simulation -- npx vitest bench
# etc.
# For exec harness
codspeed run -m walltime
-
检查输出:你应该会看到结果表格和 CodSpeed 报告链接。
-
验证火焰图:对于模拟模式,请访问报告链接或使用
query_flamegraphMCP 工具,检查是否已生成火焰图。 -
告知用户完成了哪些设置,展示首批结果,并建议后续步骤(例如添加 CI 集成、运行
optimizeskill)。