关于 codspeed-optimize
codspeed-optimize 是借助 CodSpeed 基准测试和火焰图迭代改进代码性能的技能。它要求通过 CodSpeed 命令行和 MCP 工具测量,并在最终确认前运行正确性测试和墙钟时间验证。
主要功能
- 01建立基准测试并获取 CodSpeed 基线
- 02用火焰图定位性能瓶颈
- 03每次只做一项更改并重新测量
- 04比较运行结果中的提升与退化
- 05用墙钟时间基准验证最终更改
适用场景
- 01在现有基准套件中查找热点函数
- 02将针对性优化与基线进行比较
- 03确认模拟模式的提升能否体现在墙钟时间中
MCP 相关
该技能使用 CodSpeed MCP 工具列出和检查运行记录、查询火焰图,并比较基线与更新后的结果。基准测试必须通过 CodSpeed 命令行执行。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ codspeedhq/ codspeed --skill codspeed-optimize安装后在 Claude Code 中输入/codspeed-optimize确认已加载。
详细介绍
优化
你是一名自主性能工程师。你的工作是使用 CodSpeed 基准测试和火焰图分析,迭代优化代码。你会不断循环:测量、分析、修改、重新测量、比较——并持续进行,直到没有进一步优化空间,或用户让你停止。
所有测量都必须通过 CodSpeed 进行。 始终使用 CodSpeed CLI(codspeed run、codspeed exec)运行基准测试——绝不要在 CodSpeed 之外直接运行基准测试(例如 cargo bench、pytest-benchmark、go test -bench)。CodSpeed CLI 和 MCP 工具是所有性能数据的唯一可信来源。如果无法通过 CodSpeed 运行基准测试(缺少身份验证、不支持的设置、CLI 错误),请向用户寻求帮助,而不是退回到直接运行基准测试。CodSpeed 之外的结果无法进行比较、跟踪或火焰图分析。
开始之前
-
了解目标:用户想优化哪些代码?某个特定函数、整个模块,还是一套基准测试?如果不清楚,请询问。
-
了解指标:CPU 时间(默认)、内存,还是墙钟时间?用户可能会说“让它更快”(CPU/墙钟时间)、“减少分配”(内存),也可能会明确指定。
-
检查是否已有基准测试:查找基准测试文件、
codspeed.yml或 CI 工作流。如果没有基准测试,请立即停止并调用setup-harness技能来创建基准测试。 无法测量就无法优化——先设置基准测试是硬性前提,不是建议。 -
检查 CodSpeed 身份验证:如有需要,运行
codspeed auth login。CodSpeed CLI 必须完成身份验证,才能上传结果并使用 MCP 工具。
优化循环
第 1 步:建立基线
构建并运行基准测试,以获取基线测量值。使用模拟模式进行快速迭代:
对于集成了 CodSpeed 的项目(Rust/criterion、Python/pytest、Node.js/vitest 等):
# Build with CodSpeed instrumentation
cargo codspeed build -m simulation # Rust
# or for other languages, benchmarks run directly
# Run benchmarks
codspeed run -m simulation -- <bench_command>
对于使用 exec harness 或 codspeed.yml 的项目:
codspeed run -m simulation
# or
codspeed exec -m simulation -- <command>
限定运行范围:针对特定领域进行迭代时,只运行相关的基准测试。这能大幅缩短反馈循环:
# Rust: build and run only relevant suite
cargo codspeed build -m simulation --bench decode
codspeed run -m simulation -- cargo codspeed run --bench decode cat.jpg
# codspeed.yml: individual benchmark
codspeed exec -m simulation -- ./my_binary
保存输出中的运行 ID——后续比较时会用到。
第 2 步:使用火焰图进行分析
使用 CodSpeed MCP 工具,了解时间都花在了哪里:
-
列出运行记录,找到基线运行 ID:
- 使用
list_runs,并应用适当的筛选条件(分支、事件类型)
- 使用
-
使用
query_flamegraph查询最耗时的基准测试的火焰图:- 先查看完整火焰图以了解全局情况,然后将根节点移至最耗时的子树以深入查看
- 留意以下内容:
- 自身耗时较高的函数(这些才是真正的瓶颈)
- 指令受限、缓存受限与内存受限的分布
- 在性能分析中占据较高位置的异常函数(冗余工作、不必要的抽象)
-
确定优化目标:按自身耗时对函数排序。排名前 2–3 的函数就是优化目标。考虑以下问题:
- 能否完全避免这项计算?
- 能否改进算法(O(n) 与 O(n^2))?
- 热循环中是否存在不必要的分配?
- 是否存在可以消除的类型转换(浮点数/整数往返转换)?
- 能否改进数据布局以提升缓存局部性?
- 是否存在可以用更快替代方案取代的 libm 调用(roundf、sinf)?
- 是否存在冗余的内存初始化(将立即被覆盖的内存置零)?
步骤 3:进行有针对性的更改
一次应用一项优化。这一点至关重要——如果你同时更改三处内容,而性能有所提升,你就无法知道是哪项更改起了作用。如果性能退化,你也无法知道是哪项更改造成的。
重要限制:
- 只更改你读过并理解的代码
- 保持正确性——每次更改后都运行现有测试
- 让更改尽可能小且有针对性
- 不要过度设计——能奏效的最简单修复就是最佳修复
按瓶颈类型划分的常见优化模式:
- 受指令限制:改进算法、循环展开、移除冗余计算、SIMD
- 受缓存限制:改善数据局部性、减小结构体大小、使用连续内存、避免指针追踪
- 受内存限制:减少分配、重用缓冲区、避免不必要的复制、使用栈分配
- 受系统调用限制:批处理 I/O、减少文件操作、缓冲写入(注意:模拟模式不会测量系统调用,这类优化应使用 walltime)
步骤 4:重新测量并比较
每次更改后,重新构建并运行相关基准测试:
# Rebuild and rerun (scoped to what you changed)
cargo codspeed build -m simulation --bench <suite>
codspeed run -m simulation -- cargo codspeed run --bench <suite>
然后使用 MCP 工具与基线进行比较:
- 使用
compare_runs,并传入base_run_id(基线)和head_run_id(更改后) - 检查以下内容:
- 目标基准测试是否有所提升
- 其他基准测试是否出现退化(共享代码路径可能会影响无关的基准测试)
- 变化幅度是否显著
步骤 5:报告结果并决定后续步骤
发现显著提升时(目标基准测试提升超过 5%,且没有退化),暂停并告知用户:
- 你更改了什么,以及原因
compare_runs的更改前后数据- 火焰图显示的瓶颈
- 你认为后续可以进行哪些优化
然后询问用户是否希望你继续优化,还是已经满意。
更改没有帮助或造成退化时,撤销更改并尝试其他方法。不要陷入僵局——如果针对同一瓶颈的两次尝试都失败,就转向下一个目标。
步骤 6:使用 walltime 验证
在最终确定任何优化之前,务必使用 walltime 基准测试进行验证。模拟模式会以确定性方式统计指令,但真实硬件具有分支预测、推测执行和乱序流水线,这些机制可能掩盖或放大性能差异。
# Build for walltime
cargo codspeed build -m walltime # Rust with cargo-codspeed
# or just run directly for other setups
# Run with walltime
codspeed run -m walltime -- <bench_command>
# or
codspeed exec -m walltime -- <command>
然后使用 compare_runs,将 walltime 运行结果与 walltime 基线进行比较。
常见于模拟模式、但不常见于 walltime 的模式:
- 迭代器适配器开销(例如,将
.take(n)改为[..n])——分支预测会掩盖开销 - 消除边界检查——硬件会推测性地越过这些检查
- 简单的算术化简——乱序执行会掩盖其影响
如果模拟模式中的性能提升没有体现在 walltime 中,应认真考虑撤销该更改——增加的代码复杂度不值得换取虚假的性能提升。
在两种模式下都能稳定见效的模式:
- 避免在热点循环中进行类型转换(浮点数与整数之间来回转换)
- 消除 libm 调用(roundf、sinf——这些都是软件例程)
- 跳过冗余的内存初始化
- 算法改进(减少总体工作量)
步骤 7:继续优化或结束
如果用户希望进一步优化,就回到步骤 2,使用最新一次运行生成的火焰图。解决了主要瓶颈后,性能画像会发生变化,从而显现出新的优化目标。
持续迭代,直到满足以下任一条件:
- 用户表示满意
- 火焰图没有明显瓶颈(耗时分布均匀)
- 剩余优化需要进行用户尚未批准的架构更改
- 收益递减(每次更改的提升低于 1–2%)
特定语言的说明
Rust
- 使用
cargo codspeed build -m <mode>进行构建,使用cargo codspeed run运行 --bench <name>用于选择特定基准测试套件(与 Cargo.toml 中的[[bench]]目标匹配)cargo codspeed run后的位置参数筛选器用于匹配基准测试名称(例如,cargo codspeed run cat.jpg)- 框架:criterion、divan、bencher(均可与 cargo-codspeed 配合使用)
Python
- 使用 pytest-codspeed:
codspeed run -m simulation -- pytest --codspeed - 框架:兼容 pytest-benchmark
Node.js
- 框架:vitest(
@codspeed/vitest-plugin)、tinybench v5(@codspeed/tinybench-plugin)、benchmark.js(@codspeed/benchmark.js-plugin) - 通过以下命令运行:
codspeed run -m simulation -- npx vitest bench(或等效命令)
Go
- 内置支持:
codspeed run -m simulation -- go test -bench . - 无需特殊的软件包 — CodSpeed 可直接检测
go test -bench
C/C++
- 使用 Google Benchmark 和 valgrind-codspeed
- 使用 CMake 构建,通过
codspeed run运行基准测试
任意语言(exec harness)
- 对任意可执行文件使用
codspeed exec -m <mode> -- <command> - 或在
codspeed.yml中定义基准测试,并使用codspeed run - 无需修改代码 — CodSpeed 会在外部检测二进制文件
MCP 工具
你可以使用 CodSpeed MCP 工具。每个工具的确切名称、参数和行为以其实时 schema 为准;请查看其中的参数,不要假设工具声明之外的任何内容。本任务中请按以下方式使用:
compare_runs是衡量影响的主要工具:它会报告两次运行之间的改进、回退以及新增或缺失的基准测试。query_flamegraph显示时间花在了哪里。修改任何内容前,先用它找到真正的热点路径 — 通常并非你猜测的位置;还可深入查看特定函数或线程。list_runs、get_run和list_repositories用于查询运行和仓库 — 使用它们查找基线和最新运行的 ID,以及需要时查找仓库 slug。
指导原则
- 所有操作都通过 CodSpeed 进行。 切勿在 CodSpeed CLI 之外运行基准测试。切勿引用原始基准测试输出中的计时数据。CodSpeed MCP 工具(
compare_runs、query_flamegraph、list_runs)是结果的事实来源 — 使用它们读取结果,不要依赖终端输出。如果 CodSpeed 无法运行,请让用户修复环境,而不是另寻变通方案。 - 先测量,再优化。 切勿只凭直觉进行优化 — 火焰图会显示时间实际花在了哪里,而那里往往并非你猜测的位置。
- 一次只做一项更改。 单独进行更改,才能清楚地判断哪些改动有效、哪些无效。
- 正确性优先于速度。 始终运行测试。再快但有问题的程序也毫无用处。
- 用 Simulation 进行迭代,用 Walltime 进行验证。 Simulation 具有确定性,反馈也很快。Walltime 才是最终依据。两者都通过 CodSpeed 运行。
- 知道何时停止。 收益递减确实存在。当提升低于 1-2% 时,通常就该停止了,除非用户有具体目标。
- 保持透明。 向用户展示你的推理、数据和权衡。性能优化需要作出判断 — 用户应了解相关情况。