measureBlock:性能测试如何在iOS中工作?

抬起头,我们已经搬家了! 如果您想继续了解Square的最新技术内容,请访问我们的新家https://developer.squareup.com/blog

我在Square的一个小型项目中工作,涉及iOS的性能单元测试-本质上,研究如何引入性能单元测试,我们的选择是什么以及如何在CI(持续集成)上扩展。 在关注Apple作为其单元测试套件的一部分提供的一种神奇的measureBlock方法时,问题是:它如何工作? 而且,这对我们和CI流程都有效吗?

什么是measureBlock?

对于那些不知道measureBlock,有一点背景知识:当您在XCTest编写单元测试时,可以使用一项功能来测量执行代码块所需的时间。 在Objective-C中看起来像这样:

它是如何工作的?

基础

不幸的是,在我偶然发现2014年WWDC会议的一些旧幻灯片之前,Google的业绩还很低。

本文档说明measureBlock 运行您的块10次,并计算运行块所需的平均时间。 然后将该平均值用作基线。 第一次运行测试时,它会失败,因为尚未建立基线,因为该基线是在第一次运行时计算得出的。 您可以手动修改该基准。 在随后的测试运行中, measureBlock仍然会运行您的模块10次,但这一次它将把运行时间的标准偏差与基线进行比较。 如果向上或向下的折扣超过10%,则您的测试将失败。 所有这些设置也可以手动更改。

基线与平均值

Xcode显示了一个弹出窗口,它同时显示了基线和平均值。 两者之间的区别是:平均是上次运行测试运行代码块所花费的时间。 基线是您选择的固定设置(如果不执行,则由Xcode自动设置)。 将标准偏差与基线进行比较; 弹出窗口中显示的平均值对您的测试没有任何影响。

为什么使用标准偏差

以下图表显示了给定代码块10次运行的运行时间:

平均时间为1秒。 (摘自Apple WWDC幻灯片)

现在,这是第二个图表,其中平均时间也是1秒:

显然,平均水平并不能说明全部情况。 这就是measureBlock将标准偏差与基线进行比较的原因-因为标准偏差告诉我们有关测量范围的信息。

基线存储在哪里?

因此,对于那些在多台计算机上运行CI的大公司工作的人来说,现在面临的主要问题是:基线存储在哪里? 我只是通过使用git,添加性能单元测试并查看文件diff来弄清楚这一点。

Xcode将基线存储在project.xcodeproj/xcshareddata/xcbaselines/...下的项目文件包中。 此文件夹将包含一个.plist列出给定主机+运行目标组合的所有性能测试设置,以及一个包含所有主机列表的Info.plist 。 基线特定于运行测试的主机和目标设备(例如,iPhone 7模拟器)。 Xcode生成唯一的UUID来识别组合(机器+目标),并将所有性能设置绑定到该组合。 该组合由计算机的规格定义-因此,如果您在具有完全相同的规格的另一台计算机上运行性能测试,则将拉取相同的基准(请参见下面的屏幕快照,了解用于定义组合的规格) 。

索引所有主机和目标组合的Info.plist如下所示:

这是给定主机性能测试设置的.plist的示例:

因此,当将这些检查到您的代码存储库中时,每台机器都必须具有自己的设置。 这是合理的,因为主机之间的性能会有所不同,模拟器也会有所不同。 但是,如果您在一家大型公司拥有数百台虚拟机,则可能会变得棘手。

问答环节

  • 这是什么版本的Xcode?
    Xcode 9.2
  • 您是如何找出这些人的?
    我使用Xcode对基准进行了更改,并使用git来检测文件更改。 然后,我打开了塑料柱,尝试手工修改它们,然后查看结果。 我还尝试在另一台计算机上运行测试,以了解提取哪些基准。
  • 我可以生成带有脚本的文件吗?
    是的(只要苹果不做任何改变)。 您可以生成一个随机的UUID来命名一个组合,并插入所需的所有规格。 只要确保不要忘记任何字段即可。 Info.plist 文件需要包含对组合(机器+目标)的引用并包含规范。 您还需要一个以UUID命名的文件, 扩展名为 .plist ,其中包含所有测试名称和相关的基准。
  • 我可以从plist中删除字段以使其更通用,并为多种类型的机器或目标重新使用“组合”吗?
    不能。如果某个组合与计算机的规格不完全匹配,则Xcode将生成一个新的UUID,并用计算机的准确规格填充它。 这将要求您添加新的基准以与此UUID绑定。

结论

有关measureBlock关键确定:

  • measureBlock将您的代码块运行10次。
  • 比较标准偏差和基线。
  • 基线由Xcode计算,但可以手动设置。
  • 测试的基准存储在.xcodeproj文件中,但特定于主机和目标设备。

从本质上讲,Apple为iOS开发人员提供了一个出色的,简单的性能单元测试工具。 但是,如果没有大量额外的工具和脚本编写,它可能无法对在数百台规格不同的机器上运行自动化测试的公司进行扩展。

参考文献

  • 在WWDC 2014的Xcode 6中进行测试