11

我正在做一个非常需要一些性能调整的项目。

如果我的优化没有提高程序的速度,我该如何编写失败的测试?

详细说明一下:

问题不在于发现要优化哪些部分。我可以为此使用各种分析和基准测试工具。

问题在于使用自动化测试来证明特定优化确实具有预期的效果。如果我以后可以使用测试套件来发现可能的性能回归,那也是非常可取的。

我想我可以运行我的分析工具来获取一些值,然后断言我的优化代码会产生更好的值。然而,明显的问题是基准值不是硬值。它们因当地环境而异。

那么,总是使用同一台机器进行这种集成测试的答案是什么?如果是这样,您仍然必须考虑结果中的一些模糊性,因为即使在相同的硬件上,基准测试结果也可能会有所不同。那么如何考虑到这一点呢?

或者答案可能是保留旧版本的程序并比较前后的结果?这将是我的首选方法,因为它主要与环境无关。有没有人有这种方法的经验?我想只有在最新版本的性能至少与前一个版本一样好的情况下,如果所有测试都可以通过,则只需要保留一个旧版本。

4

9 回答 9

6

我怀疑应用 TDD 来提高性能是一个错误。无论如何,用它来获得好的设计和工作代码,并使用在 TDD 过程中编写的测试来确保持续的正确性——但是一旦你拥有了良好的代码和一套可靠的测试,你就处于良好状态调整,并应用不同的(来自 TDD)技术和工具。

TDD 为您提供良好的设计、可靠的代码和测试覆盖安全网。这会让你进入一个调整的好地方,但我认为由于你和其他人提到的问题,它不会让你在调整的道路上走得更远。作为 TDD 的忠实拥护者和支持者以及实践者,我这么说。

于 2009-04-16T17:35:10.713 回答
3

首先,您需要为可接受的性能建立一些标准,然后您需要设计一个在使用现有代码时无法满足该标准的测试,然后您需要调整代码的性能,直到它通过测试。你可能会有不止一个性能标准,你当然应该有不止一个测试。

于 2009-04-15T13:15:18.557 回答
3

在许多服务器应用程序(可能不是您的情况)中,性能问题仅在并发访问和负载下表现出来。因此,测量例程执行的绝对时间并尝试改进它并不是很有帮助。即使在单线程应用程序中,这种方法也存在问题。测量绝对常规时间依赖于平台提供的时钟,这些并不总是很精确;您最好依靠例行程序的平均时间。

我的建议是:

  • 使用分析来识别执行次数最多且花费最多时间的例程。
  • 使用JMeterGrinder之类的工具来详细说明具有代表性的测试用例、模拟并发访问、将您的应用程序置于压力之下并测量(更重要的是)吞吐量和平均响应时间。这将使您更好地了解从外部角度看您的应用程序的行为方式。

虽然您可以使用单元测试来确定应用程序的一些非功能方面,但我认为上面给出的方法将在优化过程中提供更好的结果。在单元测试中放置与时间相关的断言时,您将不得不选择一些非常近似的值:时间可能会根据您用于运行单元测试的环境而有所不同。您不希望仅仅因为您的一些同事使用劣质硬件而导致测试失败。

调优就是找到合适的东西来调优。您已经有一个正常运行的代码,因此将与性能相关的断言放在事后而不建立代码的关键部分可能会导致您浪费大量时间来优化应用程序的非必要部分。

于 2009-04-15T14:15:46.960 回答
2

记录当前代码的运行时间。

if (newCode.RunningTime >= oldCode.RunningTime) Fail
于 2009-04-15T13:16:36.523 回答
1

在 CI 服务器中运行测试 + 分析。您还可以定期运行负载测试。

您担心差异(正如您所提到的),因此它与定义绝对值无关。有一个额外的步骤,将这次运行的性能测量值与最后一次构建的性能测量值进行比较,并将差异报告为 %。您可以为重要的时间变化竖起红旗。

如果您关心绩效,您应该有明确的目标,并坚持这些目标。您应该在整个系统上进行测试来衡量那些。即使您的应用程序逻辑很快,您也可能会遇到导致您错过目标的视图问题。您也可以将其与差异方法结合使用,但对于这些方法,您对时间变化的容忍度较低。

请注意,您可以在您的开发计算机上运行相同的进程,只使用该计算机中以前的运行,而不是开发人员之间共享的。

于 2009-04-16T10:07:01.893 回答
0

还没有遇到这种情况;)但是,如果我这样做了,这就是我的处理方式。(我想我是从 Dave Astel 的书中学到的)

第 1 步:提出“可接受的性能”规范,例如,这可能意味着“用户需要能够在 N 秒(或毫秒)内完成 Y”
第 2 步:现在编写一个失败的测试。使用您友好的计时器类(例如,.NET 有 StopWatch 类)和Assert.Less(actualTime, MySpec)
Step#3:如果测试已经通过,那么您就完成了。如果是红色,则需要优化并使其变为绿色。一旦测试变为绿色,性能现在是“可接受的”。

于 2009-04-20T15:08:02.077 回答
0

对于调优本身,可以直接对比新旧代码。但不要保留两个副本。这听起来像是一场噩梦。此外,您只是将一个版本与另一个版本进行比较。功能的更改可能会减慢您的功能,这是用户可以接受的。

就个人而言,我从未见过“必须比上一个版本更快”类型的性能标准,因为它很难衡量。

您说“非常需要性能调整”。在哪里?哪些查询?有哪些功能?谁说,企业,用户?什么是可接受的性能?3秒?2 秒?50 毫秒?

任何性能分析的起点都是定义通过/失败标准。一旦你有了这个,你就可以自动化性能测试。

为了可靠性,您可以使用(简单)统计方法。例如,在相同的条件下运行相同的查询 100 次。如果 95% 的人在 n 秒内返回,那就是通过。

就个人而言,我会在集成时从标准机器或集成服务器本身执行此操作。在某处记录每个测试的值(巡航控制对于这类事情有一些不错的功能)。如果您这样做,您可以看到性能如何随着时间的推移以及每次构建的进展情况。您甚至可以制作图表。经理喜欢图表。

在进行性能测试时,无论您是否进行自动化测试,始终很难拥有稳定的环境。无论您如何开发(TDD、Waterfall 等),您都会遇到这个特殊问题。

于 2009-04-17T07:11:03.700 回答
0

kent beck 和他的团队自动化了 TDD 中的所有测试。

在这里进行性能测试,我们也可以在 TDD 中自动化测试。

性能测试的标准是我们应该测试是或否的情况

如果我们很好地了解规范,我们也可以在 TDD 中自动化它们

于 2012-01-09T06:58:15.010 回答
0

虽然我大致同意 Carl Manaster 的回答,但使用现代工具,可以将TDD 为功能测试提供的一些优势转化为性能测试。

使用大多数现代性能测试框架(我的大部分经验是使用Gatling,但我相信大多数性能测试框架的新版本也是如此),可以将自动化性能测试集成到持续集成构建中,并对其进行配置,以便如果不满足性能要求,CI 构建将失败。

因此,如果可以事先商定您的性能要求是什么(对于某些应用程序,可能由与用户或客户商定的 SLA 驱动),如果更改导致性能问题,这可以为您提供快速反馈,并确定需要性能的领域改进。

良好的性能要求是“当每小时有 5000 个订单时,95% 的用户旅程应该包括不超过 10 秒的等待时间,并且屏幕转换不超过 1 秒”。

这还依赖于在 CI 管道中部署到类似生产的测试环境。

但是,使用性能需求来推动开发可能仍然不是一个好主意,就像使用功能需求一样。对于功能需求,您通常在运行应用程序之前对它是否会通过测试有一些了解,并且尝试编写您认为会通过的代码是明智的。就性能而言,尝试优化性能尚未衡量的代码是一种可疑的做法。您可以在某种程度上使用性能结果来推动您的应用程序开发,而不是性能要求

于 2015-11-23T13:11:01.107 回答