如果性能下降太多,是否可以使用 Benchmark.NET 使 CI 构建“失败”?

ria*_*njs 6 performance-testing benchmarkdotnet

我有单元测试。如果其中之一失败,我的构建就会失败。

我想将相同的原则应用于性能。我有一系列针对通过库的几个热路径的微基准测试。根据经验,这些领域的放缓对图书馆的整体性能产生了不成比例的影响。

如果有某种方法可以有一些“性能构建”的概念,如果性能回归太显着,它可能会失败,那就太好了。

我曾考虑过不得超过的硬编码阈值。就像是:

Assert.IsTrue(hotPathTestResult.TotalTime <= threshold)

但是将其与绝对值挂钩是硬件和环境相关的,因此很脆弱。

有没有人实现过这样的东西?微软为 Kestrel 做了什么?

小智 5

我不会通过单元测试来做到这一点——这是错误的地方。在构建/测试脚本中执行此操作。您获得了更大的灵活性,可以做更多可能需要的事情。

一个粗略的轮廓是:

  1. 建造
  2. 运行单元测试
  3. 运行集成测试
  4. 运行基准测试
  5. 将基准测试结果上传到结果存储(商业产品,例如“PowerBI”)
  6. 用以前的结果检查当前结果
  7. 上传人工制品/部署包

6. 如果出现回归,您可以使用非零退出代码让构建失败。
BenchmarkDotNet 可以将结果导出为 JSON 等,因此您可以利用它。

关键是如何确定是否发生回归。特别是在 CI 构建(使用容器等)上,不同的基准测试可能有不同的硬件,所以结果不是 1:1 可比的,你必须考虑到这一点。
就我个人而言,我不会让脚本在可能出现回归的情况下失败,但它会发送有关该问题的信息,因此我可以手动检查它是真正的回归还是只是由不同硬件造成的。

如果当前结果比最近 5 个结果的中位数差,则简单地检测到回归。当然,这是一种粗略的方法,但它是一种有效的方法,您可以根据需要对其进行调整。