---
name: performance-testing
description: 当用户要求测量、基准测试、比较、分析、诊断或改善运行时性能时使用，包括延迟、吞吐量、CPU、内存、可扩展性、负载、压力、耐久或性能回归。建立受控条件，采集可重复的基线与候选结果，分析波动和原因，在实际执行测量时保留有证据的性能日志，并只在调查后建议应对方案。不要用于仅验证正确性的测试、没有性能问题的功能缺陷、推测性清理、依赖升级，或未经明确授权的生产环境负载生成。
---

# Performance Testing

## 目的

使用可复现的证据测量并解释性能变化。

遵循以下核心循环：

1. 定义决策与指标。
2. 选择能够回答问题的最小测试。
3. 建立受控基线。
4. 在等价条件下测量候选方案。
5. 确认并分类差异。
6. 在选择应对方案前分析原因。
7. 重新测量并记录结论。

目标不是让每个候选方案看起来更快，而是判断发生了什么、为什么发生、是否重要，以及证据支持什么行动。

## 不可妥协的规则

- 在选择工具或修改代码前定义性能问题。
- 优先使用仓库已有的基准、分析和负载测试工具。
- 比较等价的工作负载、数据、构建、环境和运行时状态。
- 记录原始数值、单位、重复次数和相关波动，不要只报告百分比。
- 区分观测结果、解释、假设和已确认原因。
- 不要因为一次结果较差就自动更换方案或回滚。
- 不要仅凭 profile、trace 或相关性断言因果关系。
- 保持功能正确性；性能改善不能为错误行为辩护。
- 未获得明确授权并设定安全限制时，不要对生产或第三方系统施加负载。
- 未实际运行的 benchmark、profile 或比较不得声称已运行。
- 仅在用户要求实现改善时修改性能相关代码，并保持变更聚焦。

## 工作流程

### 1. 明确决策

识别：

- 被测系统、操作、代码路径、端点或工作负载；
- 测量需要支持的决策；
- 主要指标和重要保护指标；
- 相关工作负载与运行条件；
- 已有的性能预算、SLO、阈值或基线；
- 用户只需要测量、需要诊断，还是需要实现改善。

不要在看到结果后再制造通过标准。没有阈值时，如实报告测得的权衡。

### 2. 检查项目并选择测试层级

阅读适用的项目说明、已有 benchmark、性能测试、构建模式、fixture、脚本、CI 配置和相关历史。

选择最小且有代表性的层级：

- 针对算法或热点函数的 microbenchmark；
- 针对子系统边界的 component 或 integration benchmark；
- 针对用户延迟和吞吐量的 end-to-end 或 load test；
- 针对饱和点和失败行为的 stress test；
- 针对泄漏和长期退化的 soak test；
- 在观察到性能影响后用于定位的 profiler 或 trace。

不要用无法代表用户工作负载的方便 microbenchmark 替代真实问题。

设计新 benchmark、选择指标或阈值、判断噪声结果时，阅读 [measurement-quality.md](references/measurement-quality.md)。

### 3. 设计受控实验

执行前记录：

- 基线和候选 revision 或状态；
- 构建模式、运行时与依赖版本、硬件或 runner、相关配置；
- 工作负载、数据集、并发、持续时间、缓存状态、冷启动或热状态；
- warm-up 策略、重复次数、样本量和测量命令；
- 主要指标、保护指标和已有判断标准。

可行时一次只改变一个主要实验变量。条件无法保持一致时，记录差异并降低结论置信度。

### 4. 开始性能日志

实际运行 benchmark、load test 或 profile 时，为该调查创建或更新一个日志。

1. 优先遵循仓库已有约定。
2. 没有约定时使用 `docs/performance/YYYY-MM-DD-<short-slug>.md`。
3. 使用 [performance-log-template.md](assets/performance-log-template.md) 作为起始结构。
4. 大型原始输出、profile 和 trace 应通过链接引用，而不是粘贴进 Markdown。
5. 将不确定结果和失败的优化尝试追加到同一调查日志。

不要把运行日志写入已安装的 skill 目录。只做计划而未执行测量时，不要创建空日志。

### 5. 建立基线

运行最小且有代表性的命令。记录命令、条件、原始结果位置、汇总统计和异常。

运行时或系统需要时进行 warm-up；冷启动重要时保留冷启动测量。优先执行多次 trial。基线不稳定时，先调查不稳定性再比较候选方案。

不要为了获得基线而破坏性修改分支或工作树。使用已有 artifact、安全 worktree 或 benchmark 设施，否则明确说明只能测量一个状态。

### 6. 测量候选方案

在等价条件下运行相同工作负载。保持指标定义、单位、采样和聚合方式一致，同时记录绝对与相对差异。

必要时记录 correctness、error rate、CPU、memory、allocation 或资源成本等保护指标，以发现主要指标掩盖的权衡。

### 7. 确认并分类结果

将结果分类为：

- 改善；
- 回归；
- 混合权衡；
- 无实质差异；
- 无法判断。

在认定改善或回归前，检查 trial 波动、环境变化、warm-up、缓存状态、后台负载、数据漂移、错误和测量工具开销。

### 8. 调查回归和意外结果

候选方案更差、结果混合或不符合预期时，不要立即丢弃、切换实现或回滚。

1. 确认影响超过预期测量波动。
2. 定位受影响的指标、百分位、工作负载、阶段和资源。
3. 建立多个合理原因假设。
4. 选择能区分主要假设的最小实验。
5. 仅在需要时使用 profiling、tracing、query plan、allocation data、counter 或受控消融。
6. 同时记录支持和反对证据。
7. 使用明确的置信度陈述原因。

结果回归、出现混合权衡或需要根因分析时，阅读 [regression-analysis.md](references/regression-analysis.md)。

若正在发生的生产影响威胁可用性、成本、数据安全或关键 SLO，先控制影响。回滚可以是紧急缓解措施，但不能代替后续原因分析。

### 9. 根据证据选择应对方案

从以下方案中选择：

- 保留候选方案；
- 保留并解决局部原因；
- 调整配置或工作负载假设；
- 运行进一步区分实验；
- 尝试替代实现；
- revert 或 rollback；
- 因证据不足暂缓决策。

根据原始目标、用户影响、保护指标、已识别原因、置信度、实现成本和运行风险作出选择。不要假设未经测量的替代方案会更快。

### 10. 重新测量并验证正确性

完成优化或修正后，在相同条件下重复原始代表性测量，并运行相关正确性测试。改变必要行为换来的速度不是有效改善。

仅当 benchmark 有代表性、足够快、在可用 runner 上稳定且关联有意义预算时，才升级为永久 CI 回归门禁。否则保留可复现命令和调查日志，不要强制脆弱门禁。

### 11. 完成日志并报告

更新日志：

- 基线和候选结果；
- 绝对与相对差异；
- 波动和置信度；
- 改善、回归和不变指标；
- 原因假设与实验；
- 已确认原因或剩余不确定性；
- 选择的应对方案与理由；
- 最终重新测量与正确性检查。

最终回复先给出结果。说明测量了什么、发生了什么变化、最可信的解释、选择了什么行动以及重要限制。写入日志时提供其链接。

## 决策规则

- 将处于正常测量波动范围内的结果视为无法判断，而不是回归。
- 根据工作负载评估百分位延迟、吞吐量、错误率和资源使用，不要只依赖平均值。
- 将一个指标改善而另一个指标恶化视为需要产品或运行决策的权衡。
- 结论不同时区分冷启动、热稳态、突发和饱和行为。
- 在日志中保留失败尝试和被否定假设，避免以后重复探索。
- 数字精度不得超过测量方法能够支持的程度。
- 测试会产生显著成本、外部流量或运行风险时，先获得授权并定义停止条件。
- 无法运行代表性测量时，将静态假设或计划标记为未经验证。

## 最终报告

仅包含当前任务有证据支持的部分：

- 结果与决策；
- 基线与候选比较；
- 实验条件；
- 原因分析与置信度；
- 已采取或建议的应对方案；
- 正确性验证；
- 日志与原始 artifact 位置；
- 限制与下一项区分实验。
