为什么-drawRect比为UITableViews使用CALayers / UIViews更快?

时间:2012-08-10 21:18:11

标签: ios uitableview core-graphics

我已经可以听到一千个iOS开发人员的痛苦。

不,我不是菜鸟。

为什么-drawRect对于UITableView性能比拥有多个视图更快?

我知道合成操作是在GPU上进行的。但合成是一次性的操作;一旦层被提交到内存,它与缓存的缓冲区没有区别,从GPU的角度来看,它被转换为视图内外。将此与在drawRect中使用Core Graphics进行比较,后者在CPU上使用未知数量的操作来生成最终在CALayers中缓存的像素。如果它最终都被缓存和扁平化有什么区别呢?

此外,如果您正确处理单元重用,则不需要在每次调用-cellForRowAtIndexPath时重新生成视图。实际上,使用UIView / CALayer对象缓存的状态数据(字体,字体大小,文本颜色,属性等)比在-drawRect期间不断重新创建它们可能有性能优势。

为什么drawRect的热潮?有人可以给我指点吗?

3 个答案:

答案 0 :(得分:5)

当您谈论优化时,您需要提供特定情况和条件及限制。因为优化是关于微观管理的。否则,它毫无意义。

更快的基础是什么?你是怎么测量的?数字是多少?

例如,no-op或非常简单的-drawRect:可以更快,但并不意味着它总是如此。

我不知道CA的内部设计。所以这是我的猜测

如果是静态内容

你的绘图代码被不断调用很奇怪。因为CALayer会缓存绘制结果,并且在您发送setNeedsDisplay消息之前不会再次绘制结果。如果不更新单元格的内容,则它与单个位图图层相同。应该比多个合成图层更快,因为它不需要合成成本。如果您只使用足够小的单元格同时存在于池中,则不需要更新。随着RAM在最近的模型中变得越来越大,它更有可能发生在最近的模型中。

如果是动态内容

如果它不断更新,则表示您实际上正在自行更新它们。因此,您的图层合成版本也可能会不断更新。这意味着每个帧都会再次合成。它可能会因为复杂而庞大而变慢。如果它复杂而且很大并且有很多重叠区域,那么它可能会更慢。如果无法确定哪些区域可以忽略,我猜CA会严格绘制所有内容。不像你可以选择画什么。

如果在CPU中完成实际绘图

即使您将视图配置为多层的纯组合,也应最终绘制每个子图层。并且不保证在GPU中绘制他们的内容。例如,我相信CATextLayer正在吸引CPU。 (因为在当前移动GPU上绘制带有多边形的文本在性能方面没有意义)和一些过滤效果也是如此。在这种情况下,总体成本会相似,而且需要合成成本。

在CPU和GPU负载均衡的情况下

如果您的GPU非常繁忙,因为太多层或直接OpenGL绘图,您的CPU可能处于空闲状态。如果您的CG绘图可以在空闲的CPU时间内完成,那么它可能比为GPU提供更多负载更快。

他们都不是你的情况吗?

如果你的情况不是我上面列出的情况,我真的很想看到并检查CG代码的绘制速度比CA组合快。我希望你附上一些源代码。

答案 1 :(得分:0)

好吧,如果从GPU到基于CPU的渲染器来回移动,您的程序很容易移动并转换大量像素数据。

同样,很多层都会占用大量内存。

答案 2 :(得分:0)

我只看到一半的谈话,所以我可能会误解。基于我最近优化CALayer渲染的经验,并研究Apple所做的(不)优化的方式,你希望优化它们......

  

如果它最终都被缓存和扁平化,那有什么区别呢?

Apple最终每层创建一个单独的GPU元素。如果你有很多层,你有很多GPU元素。如果你有一个drawRect,你只有一个元素。 Apple经常不会将它们弄平,即使它们可以(并且可能“应该”)。

在许多情况下,“很多元素”都没有问题。但是如果它们变得很大......或者它们已经足够......或者它们的OpenGL尺寸不合适......并且(见下文)它们存储在CPU而不是GPU中,那么事情开始变得讨厌。 NB:根据我的经验:

  • “够”:内存40+
  • “large”:100x100点(200x200视网膜像素)

Apple的GPU元素/缓冲区代码在MOST中得到了很好的优化,但在一些地方它的优化程度非常低。表演下降就像走出悬崖一样。

  

此外,如果您正确处理细胞重用,则不需要   每次调用-cellForRowAtIndexPath

时重新生成视图

你说“正确”,除了...... IIRC Apple的文档告诉人们不要这样做,他们采用更简单的方法(恕我直言:弱文档),而是在每次调用时重新填充所有子视图。在那一点......你节省多少钱?

最后:

... iOS 6并没有改变所有这一切,创建UIView的成本大大降低了吗? (我还没有对它进行过分析,只是从其他开发者那里听说过)