大多数浏览器和
Developer App 均支持流媒体播放。
-
Instruments 入门
Xcode 中的 Instruments app 提供了丰富的工具和模板来对您的 app 进行性能分析。全面了解 Instruments,以及找出代码瓶颈的策略。了解如何利用时间性能分析和兴趣点跟踪功能对您的代码进行有意义的更改,从而大幅提高 app 的响应速度。
资源
相关视频
WWDC23
WWDC22
WWDC21
WWDC20
WWDC19
-
下载
早上好 欢迎来到 Instruments 入门指南 我的名字叫 Tibet Rooney-Rabdau 今天和我一起的是我的同事 Ben Mitchell 和 Anand Subramanian
要打造优秀的 用户体验 我第一个想到的就是性能
灵敏的响应能让你的用户 更加信任你的 App 无论我多么喜欢某个 App 的 UI 如果我不断看到加载动画 或是电量掉得很快 我获得的体验 都变得不理想了 如果你想在你的 App 中创造 很棒的用户体验 就要时刻注意这些问题 在今天的会议中 我们会与你分享我们 最爱的性能分析工具 Instruments 这对于刚刚接触 Instruments 并且想要在他们的 工作流程中集成 更好的 Instruments 的开发者来说 是非常有帮助的
性能分析不仅要趁早 还要经常进行 因为在开发过程中的 任意阶段都可能 引入回归 并且产生 复合作用 事实上 我把 Xcode Instruments 当成我最好的帮手 所以我会把它放在程序坞 Xcode 的旁边 提醒我从编程早期开始 就要经常进行性能分析 今天我们会从一个简单的介绍开始 了解一下 Instruments 的功能与特性 以及它的用户界面 然后我们会向你展示 如何用多种方式剖析你的 App 来分析它的运行耗时 我们会用一个 叫做 Time Profiler 的工具 来分析你的 App 在做什么 以及做了多少 最后 我们会讨论 在你 App 中添加 Signpost 来获取 App 行为的深度信息 让我们先简要地 了解一下 Instruments Instruments 是在 Xcode 工具集中的 一个强大的性能分析 与测试工具 Instruments 可以帮助你 在所有平台上分析你的 App 包括 iOS macOS watchOS 和 tvOS 这能让你更好地理解 并优化它们的行为和性能
你可以在开发 测试和调试 过程中使用 Instruments 另外 我有个好消息 如果你有 Xcode 那么你就已经 有 Instruments 了 在 Xcode 的“Product”菜单中选择“Profile” 尽管 Instruments 是内嵌在 Xcode 中 且经常和 Xcode 一起使用的 它还是一个单独的 App 可以在有需要的时候 单独使用 你可以自由选择 如何开始性能分析工作 现在开始 我所说的“Instruments” 会有两种不同的含义 我们已经讨论过 Instruments App 了 为什么取了个这样的名字呢 因为它提供了一系列 被称为 Instrument 的工具 帮助你分析 App 中的错误 在不容易理解 我指的到底是什么的地方 我会用“Instruments App” 来指代这个 App Instrument 会从插入在 App 进程和操作系统的 重要内部架构中 收集时间序列追踪数据 我们有时候会称 Instrument 收集到的数据为“Treat”
这里展示的是我最喜欢的几个 Instrument 左边的 Time Profiler Instrument 使用操作系统提供的内部架构 以固定的时间间隔 来收集相关线程的 所有呼叫栈 右边的 Points of Interest Instrument 从你 App 中重要的区域收集数据 让你能用多种 API 对其加以强调 比如 Signpost API 当你一开始打开 Instruments 的时候 你会看到一个模板列表 就像在“Pages 文稿”或 “Numbers 表格”中一样 模板会提供一个 预配置的 Instrument 集合 帮你解决特定的性能问题 就像“Pages 文稿”中的 生日贺卡模板一样 它会提供一个文档结构 来帮助你创建生日贺卡 Instruments 中有海量的模板 我们无法再这个短暂的会议中一一介绍 所以我们今天会着重讲讲 Time Profiler 这个模板 它包括我刚刚提到的 Time Profiler 和 Points of Interest 这两个 Instrument 以及其他
这些 Instrument 是 了解响应程度和 你 App 的占用程度的绝佳工具 当你第一次打开 Time Profiler 模板的时候 你会看到这样的 一个空白文档 等着你去进行分析工作 你可以通过点按 右上角的添加 Instrument 按钮 来为你的文档添加额外的 Instrument
然后 Instruments App 就会 展现它的资源库面板 包括了可用 Instrument 的完整清单
从这里 你可以找到新的 Instrument 并将其拖到文档中 来获取更多数据
界面的左上角是 分析控件 这让你能够记录 暂停 或者停止数据收集 分析控件旁边是目标区域 左边的目标设备列表 让你能够选择 你在分析时想用的设备 这与 Xcode 中的目标区域很像 你在那里可以选择 在设备上进行分析时 所用的设备和进程
通常来说 你都会选择 你 App 的进程做为目标进程 但是 举个例子 如果你在分析一个共享的扩展 你可能会选择扩展进程 作为目标进程 而它和你的 App 是相互独立的 当我在 Time Profiler 模板中 开始记录的时候 文档会逐渐被 追踪数据填充 另外 使用 Instruments 记录 会占用系统资源 像你的 App 一样 为了最小化对你的 App 的影响 Instruments 还提供了一个叫做 Last Few Seconds Mode(最后几秒模式)的功能 有时候也叫做 Windowed Mode(窗口模式)
Windowed Mode 会在记录结束之前 阻止 Instruments 分析或显示结果 它还会无视记录最后几秒之前 发生的事件 在你想要记录数据 并在发现问题时停止时 这个模式十分实用 有些模板默认使用这个模式 因为它们会在短时间内 收集大量的数据
现在我已经在 Time Profiler 模板中 完成了一次记录 大量的追踪数据 布满了这个窗口的 各个角落 这可能看起来很复杂 所以我们来分别看看 每个部分都在做什么
在窗口顶端的部分 包含了 Track Viewer(轨道查看器) 一个 Track 会展示与某个事件源相关的 时间序列追踪数据 比如进程 线程 或者 CPU 核心 单个的 Instrument 可能会为多个轨道 提供追踪数据 在这个例子中 我们可以看到三个轨道 最上面的轨道是 Time Profiler Instrument 提供的 一份关于我们 App 系统占用的总结 第二个轨道展示了 从 Points of Interest Instrument 收集来的信息 这一点 Anand 稍后 会为大家讲解 下面的额外轨道 把数据进行进一步的细分 一个 Instrument 的追踪会生成 数十个轨道 你可以用 Track Filter 来让它只显示 Instrument 或者按线程或 CPU 核心细分 你也可以获得更详细的数据 或者按名称来搜索轨道 在窗口的底部 详细视图让你能够 探索选定轨道的追踪信息 在这个例子中 我们选中了 Time Profiler 轨道 我们可以探索追踪过程中 每个线程调用的函数 详细视图的右半部分 你可以在检视器中 找到扩展的详细视图 这个视图可能会提供 来自正在使用的 Instrument 的 更详细的信息 取决于当前情境以及所选项 在这个例子中 由于我 在使用 Time Profiler 我会获得一个最“厚”调用栈的总结 另一个及时监控 当前情况的方式是 通过 Inspection Head(探头) Inspection Head 是一个 可以被放置在追踪中的 一个特定时间点上的选择器 以此来选中所有 在那个时刻正在发生的事件或间隔 被选中事件的额外细节 会在悬浮标签上显示 详细视图和额外详细视图 会持续更新 来在可用时跟踪 选定事件的信息
我们已经把每个部分过了一遍 现在我们对 Instruments 的 用户界面更加了解了 窗口中展示的所有内容都是 追踪文档的一部分 追踪文档包括 任何为分析工作配置好的 Instruments 也包括收集到的数据 以及你用于分析结果的视图 Instruments App 能存储 并重新打开这些追踪文档 让你能够探索之前的结果 或者把它们分享给同事 以供研究 接下来 我想邀请 我的同事 Ben Mitchell 来到舞台 他会通过实际操作 来向各位展示一下 谢谢 谢谢 Tibet Hello World 我的名字是 Ben Mitchell 正如 Tibet 所说 我会 向各位展示如何使用 Instruments 来分析你的 App 我们开始吧
对于你们中部分 看过去年的大会 WWDC2018 的人来说 可能会觉得《Solar System》App 很熟悉 我们大概在一年前上架了它 并从我们的顾客那里收获了 一些正面的反馈 但是 也有一些没那么好的反馈 具体来说 是在性能方面的 我们的顾客报告了一些 响应问题 尤其是在较早的设备上 在会议前 我重现了 其中的一个问题 我想要用 Instruments 向各位展示一下 来看看我们是不是 能够修复它 我们现在就开始吧
现在 App 已经在运行了 我们就直接打开 Instruments 吧
Instruments 的模板选择器 默认选中了 Time Profiler 因为我在之前用过它 Time Profiler 是一个 分析在某个时间窗 发生的问题的绝佳工具 我选择 Time Profiler 然后点按“Choose”按钮 打开一个新的追踪文档 由于我没有从 Xcode 打开它 我要做的第一件事情就是 选择我要追踪的进程 使用目标选取区域 我选择“All Processes” 然后选择正在运行的 “Solar System Mac”App 你可以在右边看到一个数字 那是进程标识符 它会在“活动监视器”中显示 我们已经选中了 App 现在我们点按窗口左上角的 记录按钮
来吧 Instruments 开始记录了
切换到 App 界面
《Solar System》App 支持一系列 触控板上的手势 包括点按拖动 平移 缩放 等等 我们的顾客报告说 他们在使用这些操作时 或者使用 Command-R 重载数据时 用户界面会卡住 并且会出现一个加载动画 它或者有别的叫法 这并不理想 我们能再现这个问题 所以我们切换回 Instruments 然后看看我们能找到什么 当我退出 App Instruments 会自动停止记录 我们可以看到这里的追踪数据 我要做的第一件事就是 让它变大一点 这样我们就能看到更多细节了
当光标在跟踪区域上时 用一个缩放手势 就可以放大它 让我们更清楚地看到细节
在跟踪区域的左侧 我们能看到几个 Instrument 向我们提供了轨道 Time Profiler 显示着 CPU 占用的总结 Points of Interest Instrument 目前是空的 Anand 稍后会为你展示这一点 还有很多其他的 Instrument 包括 Thermal State 其他细分信息可以在滚动视图 下方看到
如果我们把光标移动到 CPU 用量总结轨道 我们可以看到一个悬浮的标签 展示当前的占用状态
当我移动到这个大区域时 会发现占用率超过了 100% 这看起来很可疑 我怀疑这就是重新加载操作 发生的时间 我想把它和一些其他的轨道 放到一起比较 我们要用到一个叫做 Track Pinning 的功能 在窗口左侧 当我把鼠标移动到 某个轨道条目上方时 会出现一个加号按钮
点按它 就可以把它固定到 轨道区域底部 现在我们可以 滚动其他轨道 并排看着我们感兴趣的这条轨道 你可以固定多条轨道
在我们向下滚动的同时 我们可以看到系统中的 每个 CPU 核心都在这里出问题了 我们在这里还有一个 针对进程本身的轨道条目 Solar System Mac 除了 CPU 用量总结 这也向我们展示了 App 生命周期事件 我们可以看到在这里 App 来到了前台 因为那时我在程序坞点按了它 还有一个可疑的红色区域 就在 CPU 用量峰值附近这里 把鼠标移动到上面 可以看到标签上写着“Spinning”
“Spinning”在 Instruments 中 指的是 你的主线程卡住了 在 Mac 上 这就是导致出现 加载动画的原因 主线程只有几个 特别的用处 它应该被用来处理 用户的输入或者更新用户界面 显然 这里有点不太对劲
我想看看主线程
我把 Solar System Mac 这个线程展开 现在可以看到 有好多 其他的轨道 分别代表 App 中的每个线程 一直向下滚动 这就是主线程 主线程出现了一个峰 这看起来就是我想要仔细看看的事件 接下来我们要用到的 Instruments 的功能让我们能够 通过在轨道区域点按和拖动 来过滤事件
现在 底部的详细视图 只显示选定时间窗中 发生的事件 我们来深入看看详细视图 来了解更多 详细视图为我们展现了一个调用图 这些都是我们在 分析时所调用的函数 或者 在这个例子中 是在我们从过滤器选中的时间中 理解这是在做什么很重要 我们并不是在追踪 每个函数的进入和推出 其实 Time Profiler 每秒 会捕获许多次快照 并且记录你的进程中 所有正在运行的函数
所以在左侧 我们有一个等待列
Solar System Mac 在 100% 时间都有出现 这意味着 在每次采样中 Solar System Mac 都出现了 这很好 因为这正是我们 要分析的 App 我们向下继续看 可以看到主线程的出现率为 96.7% 等等 我们继续展开这些线程 来看看我们调用的 更深的函数 但是这里有很多函数 我必须点按很多次 才能找到一些有趣的东西 为此 Instruments 提供了另一个实用的技巧 如果你按住 Option 键 在点按关闭三角形 Instruments 就会自动 展开轨道列表 知道出现控制流分支 因为这可能会是我们想要找的事件 可以看到 这里有非常多 要一直深挖并且精确地 找到你的问题 会十分困难 所以 Instruments 也在 Time Profiler 的扩展详细视图 提供了最厚栈追踪
最厚栈追踪是一个 我们在分析过程中 最常调用的函数集合 所以 在最上方 我们可以看到 Solar System Mac 并且部分帧被 高亮为白色了 这些就是你自己的进程的帧
系统框架或库中的帧 会显示为灰色
所以 主线程执行主函数 然后这里有一块是 系统框架提供的函数 在更下面的这里 我们发现了 另一个高亮函数区域
这里的第一项被标记为“thunk”
那么“thunk”是什么呢 这是一段由编译器生成的帮助代码 它与你 App 中的任何代码 都没有关联 所以在这个例子中 我们可以无视它 我们想要看的是这一个 在网络请求调度程序中的 某个方法中的第一个闭包
如果我点按这一行 它就在详细视图中杯选中了 双击它就会直接在这里 显示它的源代码
所以 可以看到我们有 一个方法叫做 scheduleParsingTask 它在主分发队列中做一些事情 包括数据解析 它看起来很有问题 之前我们提到过 主线程只应该在 用户输入或更新用户界面的时候使用 所以 我想要修复一下这里 在详细视图的右上角 有一个“在 Xcode 中打开”的按钮 我来点一下
然后 Xcode 就出现了
我想要把这个移动到 它自己的分发队列中 这样它就不会阻碍主线程了
我们首先要做的事情是 创建这个分发队列 我们称之为 parsingQueue 然后 我们把工作移到 parsingQueue 中 通过一个异步闭包来实现
把 workItem() 移上来 我们还想在解析完成之后 通知用户界面 所以 我们把这个调用后面接上 DispatchQueue.main 存储 然后试试再一次 复现我们的 Bug 这一次 我在“Product”菜单中 选择“Profile” 就像 Tibet 之前演示的那样 Xcode 开始构建 App 并唤起 Instruments 模板选择器再一次弹出来了 因为这一次我们不是在测试 这个 App 的下载好的副本 我们在测试 Xcode 已经放到硬盘的 数据路径里的那个
选择“Time Profiler” 然后点按“Choose” 这一次 我们不用选取目标 因为 Xcode 已经通知了 Instruments 我们想要测试的 App 是哪一个
然后 点按左上角的记录按钮 会让它自动开始运行 切换到 App 我们来试试 那个有问题的用户输入序列 点按 拖动 Command-R 看 这一次没有加载动画了 我们再试一次来确认一下 点按 拖动 Command-R 没有加载动画 所以 我们已经处理了响应问题 停止记录 再次用缩放手势 来展开轨道视图 我想要确认这个工作 已经从主线程移除了 所以我会用轨道过滤器区域 在界面的左上角 然后我们搜索主线程
只出现了一个条目 是 Solar System Mac 的 如果我展开它 可以看到主线程是可见的
在这里 我们 CPU 用量到达峰值的地方 主线程做的事情相对较少 并且在第二个时间区间 也是相同的情况 这样看来 我们似乎已经解决了 响应问题 并且把这个工作 从主线程移除了
我想再谈谈几个分析注意事项 首先 Time Profiler 是一个 理解你的 App 是如何使用时间的 绝佳工具
可能会在有响应问题的时候用的上 比如 加载动画 也可能在你想要 加速 App 的启动 来让它更快地显示在 用户眼前的时候用得上 在这些情况中 请使用 Time Profiler
第二点 如果你遇到了响应问题 看看你的主线程 主线程真的只应该被用来 更新用户界面 或者处理用户输入事件 比如 Mac 上的鼠标点按 或是 iOS 设备上的屏幕轻点
第三点 是我之前没有提到过的 你应该在发布模式中进行分析 编译器支持一系列 不同的优化等级 当你在 Xcode 中进行 构建-运行循环的时候 我们会用一个低等级的优化 来让这个过程更快一些 但这个优化等级 并不是当你用 App Store 或 Xcode 的存档功能 把 App 递交给用户时所用的 如果你在使用 Xcode 的默认配置 在你的方法下的分析 会被设置为发布配置 然而 如果你在用 自定义编译选项 请确保 你在分析的 App 正在使用 编译选项的发布工具集
最后 使用不同负荷 或在较早设备上进行分析 十分重要 在这个例子中 我们没有在我们的设备上发现这个 Bug 但是拥有不同性能特征设备的用户 确实遇到了这个 Bug 所以 如果你有较早的设备 请确保在它们上面也进行测试 Tibet 之前提到过 Instruments 支持所有平台 我们用 Mac 进行了展示 但是在 iOS watchOS 和 tvOS 上 也同样可以使用它 它也支持模拟器 但是说到模拟器 有一点请大家务必了解
它是在你的 Mac 上运行的 这意味着它有着你的 Mac 的资源 它有你 Mac 的 CPU 和内存的性能特征 它有着你 Mac 的文件系统行为和硬盘行为 它还有这你 Mac 的散热限制 这一点当然会和 轻巧的一体化设备 有重大差异 在这个例子中 Instruments 非常适合用来 观测趋势 比如 有没有什么东西变快了或者变慢了 但是它不会给你提供 精确到秒的模拟 来告诉你 App 会怎样运行 在把 App 递交到你顾客手上之前 请确保在实体硬件上进行测试
所以 我们刚刚解决了响应问题 但是这并不是全部的问题 我们的 CPU 用量还有一个很大的峰 看起来是我们应该能削减它
CPU 用量会榨干电池容量 它会升高设备的温度 在很多 Mac 上 会导致 风扇加速运转 让你的用户感到烦躁 所以 现在我想邀请 Anand 用 Signpost 功能 来帮助我们深入了解 我们的 App 到底在做什么
谢谢 Ben
大家早上好
今天我想向你们展示如何在 代码中使用 Signpost 来增强 Instruments 从中收集的追踪 并更好地理解 你的代码时如何使用系统资源的
我们首先通过与 我们用 Time Profiler 所做的事情 进行对比 来更好地理解 Signpost Time Profiler 构建了一个 你的代码的统计分析 它是通过在一个固定时间间隔内 观测你的 App 中所有的线程 并且构建出时间和调用栈的相关分析 来实现这一点的 但是 相关分析并不能 取代精准评估 告诉你你的代码 是怎样执行的 以及为什么会执行
可能会有一块代码 在几个时间点爆发性地执行 或者 它在几个更长的时间段内 持续执行 在某些特定 Argument 上 调用的某个函数 也可能会让 CPU 持续繁忙
为了区分这几种 执行模式 你需要记录 代码的精确评估 这就引出了一个问题 你能操作的 记录性能测量的最好方式是什么
我很开心地告诉你 你不需要担心 要去打印代码 并教会 Instruments 如何读取你的打印命令 你只需要使用 Signpost
Signpost 有大量在这个用例下 十分理想的功能 它是专门为记录有结构的性能数据打造的 所以 在这种情况下 它甚至比打印还要简单高效 它提供了对评估时间的内建支持 所以 你不需要担心 你在读取的时钟源 或是你正在使用什么时钟基准 来进行评估 关于 Signpost 我最喜欢的部分是 Instruments 知道如何追踪它 让我来给你一个简单的预览 看看在代码中加入 Signpost 间隔后 我收集到的 Instruments 的追踪 是什么样子的 这里高亮的是 “Points of Interest”轨道 它展示了与某个 我在代码中加入的 Signpost 相关的重点区域
让我来给你们 具体演示一下 接着刚刚 Ben 对《Solar System》App 的研究 这是刚才的 Instruments 追踪 我们看到了这一块
熟悉的高 CPU 占用区域 我们想弄清楚为什么 我们用了这么多 CPU 时间 所以我们来向代码中使用最多 CPU 时间的部分添加一些 Signpost 让我来看看厚栈的追踪
之前 Ben 从上往下 看了这个厚栈 所以我们发现了 代码是如何在主线程开始执行的 这一次 我想要从 叶级函数开始 来了解这个负载中最耗资源 或是最常被调用的函数是什么 这里有一个叫做 setupScene() 的东西 看起来在处理很多数组 它是这个重新加载的操作中的一部分 我想要看看 它究竟使用了多少时间 所以我们去 Xcode 里看看这段代码吧 这里是 setupScene() 函数 你可以在这里看到 我之前尝试记录 性能评估的痕迹 这里有一个打印命令 在函数的开始发出 mach_absolute_time() 我们滚动到函数底部 可以看到另一个打印命令 在结束的时候 再一次显示 mach_absolute_time() 正如我之前提到过的 Instruments 并不知道如何 读取打印命令 所以我们首先需要创建一个 记录句柄 让我们能够 与 Instruments 进行通讯 我们来创建吧
我用一个叫做 pointsOfInterest 的类别 创建这个记录句柄 这个名字与 Points of Interest 这个 Instrument 相关
我们来用一个对 os_signpost API 的调用 来取代我们的第一个打印命令 它会开启一个间隔
每次你开启一个间隔的时候 都要记得结束它
与其一直向下滚动到 函数的结尾 我会选择利用 Swift 的 defer 代码块 来结束这个间隔 defer 代码块中的内容 会在当前函数结尾执行 在进行了这些修改之后 我们来构建我们的 App 并在菜单中使用“Profile”命令 在 Instruments 中对它进行分析
我们再一次选择 Time Profiler 模板 目标选择区域 已经被 Xcode 用当前的 《Solar System》App 的 构建版本填充了 我们开始记录吧
我会和 App 进行交互 并且再一次采用那个 会引发问题的操作序列 重新加载
然后我们收集到了一些数据 停止记录 我们来放大看看那个 高 CPU 占用区域
在 Time Profiler 下面 Points of Interest 轨道 现在已经被 我们在代码中加入的 重点区域填充了 有一行叫做 setupScene 这与我们的 Signpost 间隔相关 并且这里还有几个 相邻的重点区域 在轨道中被记录了下来
我预期不会有这么多 而是几个 我可以把鼠标悬浮在它们上面 并且数一数有多少个重点区域 或者我可以利用详细视图
让我来点按并拖动来 选择这一个区域 然后在 Points of Interest 轨道中 点按来重新以 Points of Interest 轨道的总结 填充详细视图 仔细看看 我发现 setupScene 在这个区域 一共发生了 8 次 每次耗时大概 200 毫秒 详细视图中有更多可用的信息 我们来点按跳转栏 并选择一个重点区域的列表 来看看在这个追踪中 录制的每个重点区域的 完整时间序列 “Duration”列展示了 它们中每一个的持续时间 我可以看到每一个间隔 都花费了差不多的时间来完成 大概 210 到 220 毫秒 这有些让人头大 难道我们在不断重复一个 工作量差不多的事情 我们看看是谁在调用 setupScene 判断一下是不是出于某种原因 它被多余地调用了 做这件事情最好的方式就是 查看 Time Profiler 记录的调用图中的信息 我们再来看看窗口右下角的 厚栈的视图 这一次我们要关注 setupScene() 的调用者 是一个叫做 prepareScene() 的函数
双击它来显示源代码
看起来 prepareScene() Scene called Setup Scene 只调用了 setupScene() 一次 所以这不是造成重复调用的根本原因 要复现完成的调用图 我们来点按跳转区域的“Root” 这会把我们带到调用图的根
我们继续在厚栈上向上看 选择下一个调用者 这里我们可以看到一个 for 循环 它很可能就是我们看到的 重复调用的罪魁祸首 我们在 Xcode 中打开这段代码 仔细看看 点按这个按钮来跳转到 Xcode 中的文件
现在我们能在 Xcode 中看到这个 for 循环了
我记得这个函数 updateWithPlanets() 的目的是 接受服务器发送给我们的数据 它是重新加载操作的一部分 然后 当有更新需求的时候 对于每个有新数据的行星 在 App 中更新它的内部模型
然而 我们可能会收到 一包对于多个行星的 更新信息数据 看起来我们在 遇到每个需要更新的行星时 都会调用 prepareScene() 来重绘整个视图
追踪向我们展示了 如果我们只更新 行星的内部模型 那么消耗的资源会大大降低 所以 我们在这里应该做的事情是 把我们所有的更新打包 放到内部模型中 并且只在所有更新完成后 重绘一次场景
这看起来是一个非常简单的修复 但是以我们的经验来看 在我们添加新功能 或者修复不相关的 Bug 的时候 大量这种类型的性能问题 都可能会溜进我们的代码中 要避免这种 Bug 呈现在我们的顾客面前 一个很好的办法是写一个 能够周期性地检查它们的功能的测试 为了节约时间 我已经写好了一个 XCTest 它会检查 App 的重新加载功能
如果我们点按测试左边的这个按钮 通常它会直接运行测试 但是我想通过辅助点按 来显示 Profile 动作 这会命令 Xcode 去在 Instruments 中构建并运行测试
我们来选择 Time Profiler 模板 并开始记录追踪 在这个测试中 我已经把重新加载操作 放到了一个对 Measure API 的调用各种 Measure API 会多次运行工作负载 来收集一些重复的评估 这非常有帮助 可以让你知道你的评估 是可重复且一致的 还是每次运行都会得到不同的结果
看起来所有的重复都停止了 所以我可以停止追踪了 我来放大看看 重点轨道的内容 我们可以看到这里有一个额外的行
最底下是我之前在代码中加入的 setupScene 间隔 在它上面是 另一个我们感兴趣的部分 由 Measure API 提供 这向我们展示了 与每次运行工作负载的迭代 相关联的间隔
一眼扫过去 我觉得工作负载 在每次运行时的行为 都差不多 所以 我只想知道 每次测试的迭代都发生了什么
除了点按并拖动 其实还有一个方便的快捷键 让你能够精确地选中 与一个轨道中的事件或间隔 相关的区域 只需要三次点按即可 这会把详细视图 用选中的特定信息填充
仔细看看 现在似乎 只有一次对 setupScene() 的调用了 这意味着什么呢? 我们使用从 Signpost 获取的信息 把我们所用的 CPU 时间减少了几个数量级
让我们来复习一下 我们刚刚遇到的概念 从 Time Profiler 或者其他地方 收集到的统计分析十分有用 它能展示那些代码被最频繁地执行 但是这并不能替代 类似我们用 Signpost API 记录的评估 因为它能告诉你 你的代码 是怎样被执行的 以及为什么会被执行
我们还看到了 运行测试是多么有帮助 它能稳定且反复地复现 我们的工作负载 并在开发循环的早期 就经常分析它
今天 我们深入探索了 会导致很高 或不合理的系统占用的 性能问题 Instruments 还有大量的模板 可以解决其他 关于资源占用的 性能问题 我们有为文件和磁盘占用而设计的模板 我们还有为网络占用设计的模板 还有一个模板 可以帮助你理解 你的 App 和操作系统或 其他系统中运行的进程 之间的关系 这还不是全部 Instruments 还有一些 十分高级的功能 自定义 Instruments 如果你是一个框架开发者 想要你使用你 API 的客户 能够解决关于性能问题 他们使用你的框架时的 性能问题 那么你可以向他们 提供一个自定义 Instruments 包 你也可以创建自定义 Instruments 模板 来在 Instruments App 中构造 一个独特的 Instruments 集合 来帮助解决某个特定的性能问题
在这个演示之后 我真的希望你们开始 在开发循环的早期 就经常分析你的代码 请在今天就去试试我们的 Instruments 11 吧 它附带了一些很棒的新功能 比如轨道固定 和结构视图 我相信它们用起来会十分有趣 在会议笔记中 我们有关于进阶功能和 针对特定事件的 Instruments 工作流的详细文档 还有一些前几年大会中的 很棒的讲解 非常感谢 [掌声]
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。