什么是持续基准测试?
持续基准测试是一种软件开发实践,团队成员频繁地对他们的工作进行基准测试,通常每个人至少每天进行一次测试 - 导致每天有多次基准测试。每个基准测试都由自动构建验证以尽快检测性能退化。许多团队发现这种方法可以显著减少性能退化,并使团队能更快地开发出高性能的软件。
到现在为止,软件行业的每个人都知道持续集成(CI)。在基础层面上,CI是在软件特性退化进入生产环节之前检测和防止它们的手段。同样,持续基准测试(CB)是在软件性能退化进入生产环节前检测和防止这些退化的手段。出于与每次代码更改都在CI中运行单元测试的同样原因,每次代码更改都应在CB中进行性能测试。事实上,这个类比如此恰当,以至于本节的第一段就是马丁·福勒 2006年关于持续集成的引言的填空版。
🐰 性能问题也是bug!
在CI中进行基准测试
误区:你不能在CI中运行基准测试
大多数基准测试工具使用系统挂钟时间来测量延迟或吞吐量。这是非常有帮助的,因为这些是我们作为开发者最关心的确切指标。然而,通用目的的CI环境在测量挂钟时间时通常嘈杂不一致。在进行持续基准测试时,这种波动性会对结果添加不必要的噪音。
处理这个问题有几个选项:
- 相对基准测试
- 专用的CI运行器
- 切换到一个使用指令次数作为标准而不是挂钟时间的基准测试工具
或者简单地接受混沌!持续基准测试不需要完美。没错,减少你的持续基准测试环境的波动性,从而减少噪声会让你检测到更精细的性能退化。然而,不要让完美成为这里的敌人!
你可能会看这个图并想,“哇,这太疯狂了!“但问问自己,你当前的开发流程能在影响到你的用户之前检测到两倍甚至十倍的性能退化吗?可能不能!现在_这个_才疯狂!
即使是从CI环境的所有噪音中,追踪挂钟基准测试仍然可以在性能退化达到你的生产环节的客户之前带来捕获性能退化的巨大回报。随着时间的推移,随着你的软件性能管理逐渐成熟,你可以从那里构建出更多。在此期间,只需使用你常规的CI就行了。
性能问题
误区:你无法察觉到100ms的延迟
通常听到人们声称人类无法感知100ms的延迟。一个Nielsen Group关于响应时间的文章经常被引用为这种观点的依据。
0.1秒大约是让用户感觉到系统在瞬间反应的极限,意味着除了显示结果之外,不需要其他特殊反馈。
- Jakob Nielsen,1993年1月__1日__
但这完全不对。在某些任务中,人们可以察觉到仅仅2ms的延迟。证明这一点的一个简单方法是Dan Luu的实验:打开你的终端并运行sleep 0; echo "ping"
然后运行sleep 0.1; echo "pong"
。你注意到了差别对吧‽
另一个常见的混淆点是区分延迟的感知和人类反应时间。尽管对视觉刺激的反应时间大约需要200ms,但这与事件本身的感知无关。举一个比喻,你可以注意到你的列车迟到了两分钟(感知延迟)即使列车的行驶时间是两小时(反应时间)。
性能很重要!性能是一个特性!
- 每快100ms → 转化率增加1%(Mobify,每年收入增加+$380,000)
- 快50% → 销售增加12% (AutoAnything)
- 快20% → 转化率增加10% (Furniture Village)
- 快40% → 用户注册增加15% (Pinterest)
- 快850ms → 转化率增加7% (COOK)
- 每慢1秒 → 用户减少10% (BBC)
随着摩尔定律的失效,能并行运行的工作负载需要并行化。然而,大多数工作负载需要串行运行,简单地抛出更多的计算问题正在迅速变成一个棘手且昂贵的解决方案。
持续基准测试是开发和维护性能强大的现代软件来应对这种变化的关键组成部分。
持续基准测试工具
在创建Bencher之前,我们设定了寻找一个工具,它可以:
- 跟踪多种语言的基准测试
- 无缝地吸收语言标准基准测试工具的输出
- 用于自定义基准测试工具的输出
- 开源并且能自我托管
- 与多个CI主机配合工作
- 用户身份认证和授权
不幸的是,没有满足所有这些标准的东西存在。参见我们从中得到灵感的现有基准测试工具的完整列表先前的艺术。
大型科技公司的持续基准测试
类似Bencher的工具在微软,Facebook (现在的Meta),苹果,亚马逊,Netflix,和谷歌等无数其他公司已经内部开发。作为行业的巨头,他们理解在开发过程中监控性能的重要性,并通过CB将这些洞察集成到开发过程中。我们建立Bencher是为了将持续基准测试从大型科技公司的墙后带到开源社区。对于与来自Big Tech的持续基准测试相关的帖子的链接,参见先前的艺术。
Bencher: 持续性能基准测试
Bencher是一套持续型的性能基准测试工具。 你是否曾经因为性能回归影响到了你的用户? Bencher可以防止这种情况的发生。 Bencher让你有能力在性能回归进入生产环境 之前 就进行检测和预防。
- 运行: 使用你喜爱的基准测试工具在本地或CI中执行你的基准测试。
bencher
CLI简单地包装了你现有的基准测验设备并存储其结果。 - 追踪: 追踪你的基准测试结果的趋势。根据源分支、测试床和度量,使用Bencher web控制台来监视、查询和绘制结果图表。
- 捕获: 在CI中捕获性能回归。Bencher使用最先进的、可定制的分析技术在它们进入生产环境之前就检测到性能回归。
基于防止功能回归的原因,在CI中运行单元测试,我们也应该使用Bencher在CI中运行基准测试以防止性能回归。性能问题就是错误!
开始在CI中捕捉性能回归 — 免费试用Bencher Cloud。
持续性基准测试与本地基准对比
有几种基准测试工具可以让你在本地对比结果。本地对比在性能调优时快速迭代很有用。然而,任何时候都不能依赖它来持续捕获性能退化。就像能够在本地运行单元测试并不能消除CI的需要,能夏在本地运行和对比基准测试也不能避免CB的必要性。
Bencher提供了许多本地基准对比工具不具备的特性:
- 在不同测试平台之间对比同一种基准测试
- 横贯不同语言和工具的基准对比
- 基准结果的协作与分享
- 在指定的测试平台上运行基准测试以减少噪音
- 不再需要复制粘贴
持续性基准测试与应用性能管理 (APM)
应用性能管理 (APM) 是现代软件服务的重要工具。然而,APM设计的目的是在生产环境中使用。等到性能回退检测出来的时候,已经影响到你的客户了。
大多数的缺陷的最终成本都比预防它们的成本要高。缺陷出现时是昂贵的,包括修复缺陷的直接成本,损坏的关系、失去的业务和开发时间的间接成本。
— Kent Beck, Extreme Programming Explained
Bencher提供了一些APM工具不能提供的特性:
- 在性能异常影响生产环境之前检测并阻止它们
- 在代码回看中包含性能变化和影响
- 在生产环境中无压力
- 在本地布置中也有效
- 不对生产源代码进行更改
持续性基准测试与可观察性
有句话说,玫瑰的其他名字会闻起来一样甜。请见上文中的 “持续性基准测试与应用性能管理” 部分。
持续性基准测试与持续集成 (CI)
持续性基准测试 (CB) 是持续集成 (CI) 的互补部分。对于每一次代码改动,单元测试在CI中运行的原因,性能测试也应该在每次改动中在CB中运行。
虽然单元和验收测试作为标准开发做法得到了大广泛的接受,这个趋势并没有延续到性能测试的领域。当前,常见的工具引导测试者创造丢弃代码和点击脚本思维。把性能测试作为头等公民使我们可以创造更好的,覆盖更多功能的测试,产生更好的工具来创建和运行性能测试,形成一个可维护并且能自我测试的测试套件。
持续性基准测试与持续负载测试
为了理解持续性基准测试和持续负载测试的区别,你需要理解基准测试 和 负载测试 的区别。
测试类型 | 测试范围 | 测试用户 |
---|---|---|
基准测试 | 函数 - 服务 | 一个 - 多个 |
负载测试 | 服务 | 多个 |
基准测试可以测试软件从函数级别(微基准)到服务级别(宏基准)的性能。基准测试非常适合以隔离的方式测试代码某一部分的性能。负载测试只能在服务级别对软件进行性能测试,并模拟多个并发用户。负载测试非常适合在特定负载下测试整个服务的性能。
🍦 想象一下我们想要跟踪冰淇淋车的性能。基准测试可以用来衡量挖一勺冰淇淋(微基准)要多长时间,基准测试也可以用来衡量单个顾客点餐,拿到他们的冰淇淋,并支付(宏基准)所需的时间。负载测试可以用来看冰淇淋车在一个炎热的夏日服务100个客户的表现如何。