如何使用 Bencher 在 CI 中跟踪基准测试
大多数基准测试结果是短暂的。 它们会在终端达到其滚动限制时消失。 一些基准测试工具允许您缓存结果,但大多数仅在本地进行。 Bencher 使您能够追踪本地和 CI 运行的基准测试并比较结果,同时仍然使用您喜欢的基准测试工具。
在持续基准测试中,也就是 CI 中的基准测试,有三种比较基准测试结果的流行方法:
- 统计持续基准测试
- 随时间跟踪基准测试结果以创建基线
- 使用此基线及统计阈值创建统计边界
- 将新结果与此统计边界进行比较以检测性能回归
- 相对持续基准测试
- 为当前基线代码运行基准测试
- 切换到新版本代码
- 为新版本代码运行基准测试
- 使用百分比阈值为基线代码创建边界
- 将新版本代码结果与基线代码结果进行比较以检测性能回归
- 变更点检测
- 偶尔为新版本代码运行基准测试
- 使用变更点检测算法来检测性能回归
- 使用二分法查找引入性能回归的提交
统计连续基准测试
从我们在快速开始和Docker 自托管教程中离开的地方继续,
让我们为我们的Save Walter White
项目添加统计连续基准测试。
🐰 请确保您已经 创建了一个 API 令牌并将其设置为
BENCHER_API_TOKEN
环境变量 然后再继续!
现在我们准备在 CI 中运行我们的基准测试。 因为每个 CI 环境都有些不同, 以下示例旨在说明而非实用。 有关更具体的示例,请参见在 GitHub Actions 中的连续基准测试 和在 GitLab CI/CD 中的连续基准测试。
首先,我们需要通过在 CI 中为每次更改进行基准测试来创建和维护我们main
分支的历史基线:
- 使用
bencher run
CLI 子命令 运行您的main
分支基准测试。 查看bencher run
CLI 子命令以获取完整概述。 (例如:bencher run
) - 设置
--project
选项为项目 slug。 查看有关--project
的文档以获取更多详情。 (例如:--project save-walter-white-1234abcd
) - 设置
--branch
选项为基础分支名称。 查看有关--branch
的文档以获取完整概述。 (例如:--branch main
) - 设置
--testbed
选项为 CI 运行器测试台名称。 查看有关--testbed
的文档以获取更多详情。 (例如:--testbed ci-runner
) - 为
main
分支、ci-runner
测试台和latency
测量设置阈值:- 将
--threshold-measure
选项设置为由bencher mock
生成的内置latency
测量。 查看关于--threshold-measure
的文档以获取更多详情。 (例如:--threshold-measure latency
) - 将
--threshold-test
选项设置为学生 t 检验(t_test
)。 查看关于--threshold-test
的文档以获取完整概述。 (例如:--threshold-test t_test
) - 设置
--threshold-max-sample-size
选项为最大样本大小64
。 查看关于--threshold-max-sample-size
的文档以获取更多详情。 (例如:--threshold-max-sample-size 64
) - 设置
--threshold-upper-boundary
选项为上限0.99
。 查看关于--threshold-upper-boundary
的文档以获取更多详情。 (例如:--threshold-upper-boundary 0.99
) - 设置
--thresholds-reset
标志以仅激活指定的阈值。 查看关于--thresholds-reset
的文档以获取完整概述。 (例如:--thresholds-reset
)
- 将
- 设置
--err
标志以在生成警报时让命令失败。 查看关于--err
的文档以获取完整概述。 (例如:--err
) - 设置
--adapter
选项为由bencher mock
生成的Bencher Metric Format JSON(json
)。 查看基准测试工具适配器以获取完整概述。 (例如:--adapter json
) - 指定基准测试命令参数。
查看基准测试命令以获取完整概述。
(例如:
bencher mock
)
第一次在 CI 中运行此命令时,
如果main
分支尚不存在,它将被创建。
新的main
将_不会_有起始点或现有数据。
将为main
分支、ci-runner
测试台和latency
测量创建一个阈值。
在后续运行中,新数据将添加到main
分支中。
然后将使用指定的阈值来检测性能回归。
现在,我们准备在 CI 中捕获性能回归。
这是我们将在 CI 中跟踪新功能分支性能的方法,恰如其名为feature-branch
:
- 使用
bencher run
CLI 子命令 运行您的feature-branch
分支基准测试。 查看bencher run
CLI 子命令以获取完整概述。 (例如:bencher run
) - 设置
--project
选项为项目 slug。 查看有关--project
的文档以获取更多详情。 (例如:--project save-walter-white-1234abcd
) - 设置
--branch
选项为功能分支名称。 查看有关--branch
的文档以获取完整概述。 (例如:--branch feature-branch
) - 为
feature-branch
分支设置起始点:- 将
--start-point
选项设置为功能分支的起始点。 查看有关--start-point
的文档以获取完整概述。 (例如:--start-point main
) - 设置
--start-point-hash
选项为功能分支起始点的git
哈希。 查看有关--start-point-hash
的文档以获取完整概述。 (例如:--start-point-hash 32ae...dd8b
) - 设置
--start-point-clone-thresholds
标志以从起始点克隆阈值。 查看有关--start-point-clone-thresholds
的文档以获取完整概述。 (例如:--start-point-clone-thresholds
) - 设置
--start-point-reset
标志以始终将分支重置为起始点。 这将防止基准测试数据漂移。 查看有关--start-point-reset
的文档以获取完整概述。 (例如:--start-point-reset
)
- 将
- 将
--testbed
选项设置为测试台名称。 查看有关--tested
的文档以获取更多详情。 (例如:--testbed ci-runner
) - 设置
--err
标志以在生成警报时让命令失败。 查看关于--err
的文档以获取完整概述。 (例如:--err
) - 设置
--adapter
选项为由bencher mock
生成的Bencher Metric Format JSON(json
)。 查看基准测试工具适配器以获取完整概述。 (例如:--adapter json
) - 指定基准测试命令参数。
查看基准测试命令以获取完整概述。
(例如:
bencher mock
)
第一次在 CI 中运行此命令时,
Bencher 将创建feature-branch
分支,因为它尚不存在。
新的feature-branch
将使用main
分支
在哈希32aea434d751648726097ed3ac760b57107edd8b
作为其起始点。
这意味着feature-branch
将具有main
分支的所有数据和阈值的副本,以便将bencher mock
的结果进行比较。
在所有后续运行中,Bencher 将重置feature-branch
分支为起始点,
并使用main
分支数据和阈值来检测性能回归。
相对持续基准测试
在快速开始和Docker 自托管教程中到此为止,让我们为我们的Save Walter White
项目添加相对持续基准测试。
🐰 确保您已创建 API 令牌并将其设置为
BENCHER_API_TOKEN
环境变量后再继续!
相对持续基准测试并排比较两版代码。这在处理噪声很大的 CI/CD 环境时会很有用,在这些环境中,可用资源在每次运行之间可能会有很大差异。在本例中,我们将比较在main
分支上运行的结果与在特性分支上运行的结果,这个特性分支被贴切地命名为feature-branch
。由于每个 CI 环境都有所不同,以下示例旨在说明而非实用。如需更具体的示例,请参阅GitHub Actions 中的持续基准测试以及GitLab CI/CD 中的持续基准测试。
首先,我们需要在 CI 中用git
检出main
分支:
然后我们需要在 CI 中运行我们在main
分支上的基准测试:
- 使用
bencher run
CLI 子命令运行您的main
分支基准测试。有关完整概述,请参阅bencher run
CLI 子命令。(例如:bencher run
) - 将
--project
选项设置为项目标识符。有关详细信息,请参阅--project
文档。(例如:--project save-walter-white-1234abcd
) - 将
--branch
选项设置为基础分支名称。有关完整概述,请参阅--branch
文档。(例如:--branch main
) - 设置
--start-point-reset
标志以始终重置基础分支。这将确保所有基准数据均来自当前 CI 运行器。有关完整概述,请参阅--start-point-reset
文档。(例如:--start-point-reset
) - 将
--testbed
选项设置为 CI 运行器测试平台名称。有关详细信息,请参阅--testbed
文档。(例如:--testbed ci-runner
) - 将
--adapter
选项设置为由bencher mock
生成的Bencher Metric Format JSON(json
)。 有关完整概述,请参阅基准测试适配器。(例如:--adapter json
) - 指定基准命令参数。有关完整概述,请参阅基准命令。(例如:
bencher mock
)
在 CI 中第一次运行此命令时,将创建main
分支,因为它尚不存在。新创建的main
将没有起始点、现有数据或阈值。在后续运行中,旧的main
Head 将被替换,并创建新的main
Head,不含起始点、现有数据或阈值。
接下来,我们需要在 CI 中用git
检出feature-branch
分支:
最后,我们准备在 CI 中运行我们的feature-branch
基准测试:
- 使用
bencher run
CLI 子命令运行您的feature-branch
基准测试。有关完整概述,请参阅bencher run
CLI 子命令。(例如:bencher run
) - 将
--project
选项设置为项目标识符。有关详细信息,请参阅--project
文档。(例如:--project save-walter-white-1234abcd
) - 将
--branch
选项设置为特性分支名称。有关完整概述,请参阅--branch
文档。(例如:--branch feature-branch
) - 设置
feature-branch
分支的起始点:- 将
--start-point
选项设置为特性分支起始点。有关完整概述,请参阅--start-point
文档。(例如:--start-point main
) - 设置
--start-point-reset
标志以始终将分支重置为起始点。这将仅使用最新的相对基准结果。有关完整概述,请参阅--start-point-reset
文档。(例如:--start-point-reset
)
- 将
- 将
--testbed
选项设置为 CI 运行器测试平台名称。有关详细信息,请参阅--testbed
文档。(例如:--testbed ci-runner
) - 设置
feature-branch
分支、ci-runner
测试平台和latency
测量的阈值:- 将
--threshold-measure
选项设置为由bencher mock
生成的内置latency
测量。有关详细信息,请参阅--threshold-measure
文档。(例如:--threshold-measure latency
) - 将
--threshold-test
选项设置为基本百分比(percentage
)。有关完整概述,请参阅--threshold-test
文档。(例如:--threshold-test percentage
) - 将
--threshold-upper-boundary
选项设置为上限0.25
。有关详细信息,请参阅--threshold-upper-boundary
文档。(例如:--threshold-upper-boundary 0.25
) - 设置
--thresholds-reset
标志,以便仅激活指定的阈值。有关完整概述,请参阅--thresholds-reset
文档。(例如:--thresholds-reset
)
- 将
- 设置
--err
标志以便在生成警报时命令失败。有关完整概述,请参阅--err
文档。(例如:--err
) - 将
--adapter
选项设置为由bencher mock
生成的Bencher Metric Format JSON(json
)。有关完整概述,请参阅基准测试适配器。(例如:--adapter json
) - 指定基准命令参数。有关完整概述,请参阅基准命令。(例如:
bencher mock
)
每次在 CI 中运行此命令时,它都将feature-branch
的结果与main
的最新结果进行比较。然后使用指定的阈值检测性能回归。
变更点检测
变更点检测使用变更点算法来评估最近结果的大窗口。这使得算法能够忽略异常值作为噪声,从而产生更少的误报。尽管变更点检测被认为是持续性基准测试,但它不允许您在CI中检测性能回归。也就是说,您无法在功能分支合并之前检测到性能回归。这有时称为“带外”检测。
例如,如果您有一个基准 bench_my_critical_path
,并且它具有以下历史延迟:5 ms
,6 ms
,5 ms
,5ms
,7ms
。
如果下一个基准结果是 11 ms
,那么统计持续基准测试阈值和变更点检测算法将会做出非常不同的解读。阈值可能会被超出并生成警报。如果这个基准运行与一个拉取请求绑定在一起,构建可能会因为这个警报而失败。然而,变更点算法暂时不会做任何事情。如果下一次运行结果下降回 5 ms
,则可能不会生成警报。相反,如果接下来的运行结果是 10 ms
和 12 ms
,那么只有这时变更点算法才会触发警报。
您对在 Bencher 中使用变更点检测感兴趣吗?如果是这样,请在跟踪问题上留下评论或直接联系我们。
🐰 恭喜!您已经学会了如何使用 Bencher 在 CI 中跟踪基准测试!🎉