第14章 性能调优

2018-09-08  本文已影响11人  cdd48b9d36e0

14.1 CPU VS GPU

Core Animation处在iOS的核心地位:应用内和应用间都会用到它。一个简单的 动画可能同步显示多个app的内容,例如当在iPad上多个程序之间使用手势切换, 会使得多个程序同时显示在屏幕上。在一个特定的应用中用代码实现它是没有意义的,因为在iOS中不可能实现这种效果(App都是被沙箱管理,不能访问别的视图)。

动画和屏幕上组合的图层实际上被一个单独的进程管理,而不是你的应用程序。 这个进程就是所谓的渲染服务。在iOS5和之前的版本是SpringBoard进程(同时管 理着iOS的主屏)。在iOS6之后的版本中叫做 BackBoard

动画过程

这4个阶段仅仅发生在你的应用程序之内,在动画在屏幕上显示之前仍然有更多的工作。一旦打包的图层和动画到达渲染服务进程,他们会被反序列化来形 成另一个叫做渲染树的图层树(在第一章“图层树”中提到过)。使用这个树状结 构,渲染服务对动画的每一帧做出如下工作:

所以一共有六个阶段;最后两个阶段在动画过程中不停地重复。前五个阶段都在 软件层面处理(通过CPU),只有最后一个被GPU执行。而且,你真正只能控制前 两个阶段:布局和显示。Core Animation框架在内部处理剩下的事务,你也控制不 了它。
这并不是个问题,因为在布局和显示阶段,你可以决定哪些由CPU执行,哪些交 给GPU去做。

GPU相关的操作

GPU的任务是:它用来采集图片和形状(三角形),运行变换,应用纹理和混合然后把它们输送到屏幕上。现代iOS设备上可编程的GPU在这 些操作的执行上又很大的灵活性,但是Core Animation并没有暴露出直接的接口。 除非你想绕开Core Animation并编写你自己的OpenGL着色器,从根本上解决硬件 加速的问题,那么剩下的所有都还是需要在CPU的软件层面上完成。
值得注意的下列事情会降低(基于GPU)图层绘制:

CPU相关的操作

CPU为Core Animation所做的工作大多都发生在动画开始之前。这意味着它不会影响到帧率,所以很好,但是他会延迟动画开始的时间,让你的界面看起来会比较迟 钝。
以下CPU的操作都会延迟动画的开始时间:

IO相关操作

还有一项没涉及的就是IO相关工作。上下文中的IO(输入/输出)指的是例如闪 存或者网络接口的硬件访问。一些动画可能需要从山村(甚至是远程URL)来加 载。一个典型的例子就是两个视图控制器之间的过渡效果,这就需要从一个nib文件 或者是它的内容中懒加载,或者一个旋转的图片,可能在内存中尺寸太大,需要动 态滚动来加载。
IO比内存访问更慢,所以如果动画涉及到IO,就是一个大问题。总的来说,这就 需要使用聪敏但尴尬的技术,也就是多线程,缓存和投机加载(提前加载当前不需 要的资源,但是之后可能需要用到)。这些技术将会在第14章中讨论。

14.2 测量,而不是猜测

于是现在你知道有哪些点可能会影响动画性能,那该如何修复呢?好吧,其实不
需要。有很多种诡计来优化动画,但如果盲目使用的话,可能会造成更多性能上的问题,而不是修复。
如何正确的测量而不是猜测这点很重要。根据性能相关的知识写出代码不同于仓促的优化。前者很好,后者实际上就是在浪费时间。
那该如何测量呢?第一步就是确保在真实环境下测试你的程序。

真机测试,而不是模拟器

保持一致的帧率

为了做到动画的平滑,你需要以60FPS(帧每秒)的速度运行,以同步屏幕刷新 速率。通过基于 NSTimer 或者 CADisplayLink 的动画你可以降低到30FPS,而 且效果还不错,但是没办法通过Core Animation做到这点。如果不保持60FPS的速 率,就可能随机丢帧,影响到体验。
你可以在使用的过程中明显感到有没有丢帧,但没办法通过肉眼来得到具体的数据,也没法知道你的做法有没有真的提高性能。你需要的是一系列精确的数据。
你可以在程序中用 CADisplayLink 来测量帧率(就像11章“基于定时器的动 画”中那样),然后在屏幕上显示出来,但应用内的FPS显示并不能够完全真实测量 出Core Animation性能,因为它仅仅测出应用内的帧率。我们知道很多动画都在应 用之外发生(在渲染服务器进程中处理),但同时应用内FPS计数的确可以对某些 性能问题提供参考,一旦找出一个问题的地方,你就需要得到更多精确详细的数据 来定位到问题所在。苹果提供了一个强大的Instruments工具集来帮我们做到这些。

Instruments

时间分析器、Core Animation、OpenGL ES驱动的混合使用

上一篇 下一篇

猜你喜欢

热点阅读