如何在Python中进行基于性能的(基准)单元测试

13
假设我的代码库已经达到了尽可能高的单元测试覆盖率(超过一定程度,增加覆盖率就没有很好的投资回报率),接下来我想要测试性能。为了基准测试代码,以确保新提交不会毫无必要地减慢速度,我对 Safari 的零容忍政策感到非常着迷。我不确定大多数项目对速度的承诺是否具有良好的投资回报率,但我至少希望收到警报,以便能够对此进行判断。环境是 Linux 上的 Python,并且建议也适用于 BASH 脚本,这将使我非常高兴。(但 Python 是主要关注点。)

似乎这个问题仍然缺乏一个好的答案。当然,通用解决方案可能不存在,但有很多可能性 - 例如,在之前和之后使用time.clock()测量时间,然后使用self.assertLess(elapsed, some_value) - 在空间(具有不同规格的机器)和时间(摩尔定律)上不可移植,但这是一个开始。 - Tomasz Gandor
4个回答

7
如果可能的话,您应该在系统级别上进行性能测试-将应用程序作为整体,在上下文中进行测试,并尽可能接近生产使用的数据和行为。
这并不容易,自动化和获得一致的结果会更加困难。
此外,您不能使用虚拟机进行性能测试(除非您的生产环境在虚拟机中运行,即使是这样,您也需要在没有其他东西的主机上运行虚拟机)。
当您说进行性能单元测试时,这可能很有价值,但仅在用于诊断确实存在于系统级别的问题(而不仅仅存在于开发人员的头脑中)时才有价值。
此外,单元测试中单元的性能有时无法反映它们在上下文中的性能,因此可能根本没有用处。

+1:AND…只有当您拥有绝对的性能目标时,性能测试才有意义。这在一般情况下很少见,但在军事和嵌入式控制系统中非常重要。 - S.Lott
4
抱歉@S.Lott - 我非常不同意你的看法。每当有两三个以上的人在一个项目上工作,并且存在期望响应能力的最终用户时,团队最好自动监控他们对目标的表现。否则,会不断添加功能,而不真正理解其对性能和客户体验的影响。 - Shane C. Mason

4

虽然我同意在系统级别测试性能最终更为相关,但如果您想要进行Python的UnitTest风格的负载测试,FunkLoad http://funkload.nuxeo.org/ 正好可以做到这一点。

当您试图加快代码库中特定操作时,微基准测试有其用武之地。完成后续性能单元测试是一种有用的方式,以确保您刚优化的此操作不会在未来提交时无意中降低性能。


4
如果像我一样,在此之后数年才发现这篇文章,请注意链接已经失效,最后一次 PyPI 上传(截至我写下这句话时)是在2015年。我想可以认为该项目已经废弃或处于休眠状态。 - greschd

2

MarkR说得对...进行真实世界的性能测试是关键,而在单元测试中可能有些棘手。话虽如此,请看看标准库中的cProfile模块。它至少对于给出提交到提交之间事物运行速度的相对感觉是有用的,而且您可以在单元测试内运行它,尽管当然你会得到包括单元测试框架本身开销的详细结果。

总之,如果您的目标是零容忍,那么您需要比这更强大的东西...在单元测试中使用cProfile完全不够,并且可能会造成误导。


2

在进行性能测试时,我通常会准备一组数据输入作为测试套件,并测量程序处理每个输入所需的时间。

你可以按日或按周记录性能,但我认为在所有功能实现之前担心性能并不特别有用。

如果性能太差,那么我会使用 cProfile 进行分析,使用相同的数据输入运行它,并尝试确定瓶颈所在。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接