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

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

不,我不是小白。

为什么-drawRect比UITableView性能要快多个视图?

我明白合成操作发生在GPU上。 但合成是一次性的操作; 一旦这些图层被提交到内存中,从GPU的angular度来看,它与caching的缓冲区没有区别。 比较一下,在drawRect中使用Core Graphics,在CPU上使用未知数量的操作来产生最终在CALayers中caching的像素。 如果这一切都结束了caching和扁平化,有什么区别?

另外,如果您正在处理单元重用,则不必在每次调用-cellForRowAtIndexPath时重新生成视图。 实际上,UIView / CALayer对象caching状态数据(字体,字体大小,文本颜色,属性等)可能会带来性能上的好处,而不是在-drawRect期间不断重新创build它们。

为什么drawRect的热潮? 有人能给我指针吗?

在谈论优化时,您需要提供具体的情况,条件和限制。 因为优化是关于微观pipe理的。 否则,这是没有意义的。

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

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

我也不知道CA的内部devise。 所以这里是我的猜测

在静态内容的情况下

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

在dynamic内容的情况下

如果它不断更新,这意味着你实际上正在更新它们。 所以也许你的图层合成版本也会不断更新。 这意味着它正在为每一帧重新合成。 它的复杂性和庞大性可能会变慢。 如果它很复杂,而且有很多重叠区域,那么速度可能会变慢。 我想如果CA不能确定哪个区域是可以忽略的,那么CA就会严格地抽取所有的东西。 不像你可以select画什么或不画。

在CPU中完成实际绘图的情况下

即使你把你的视图configuration成许多图层的纯粹构图,每个子图层也应该被绘制出来。 其内容的绘制不保证在GPU中完成。 例如,我相信CATextLayer正在绘制自己的CPU。 (因为在当前移动GPU上使用多边形绘制文本在性能方面没有意义)以及一些过滤效果。 在这种情况下,总成本是相似的,加上它需要合成成本。

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

如果您的GPU由于层数过多或者直接使用OpenGL绘图而非常繁忙,则CPU可能处于空闲状态。 如果您的CG绘图可以在空闲的CPU时间内完成,那么可能会比给GPU更多的负载更快。

他们没有一个是你的情况?

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

那么,如果从GPU到CPU的渲染器来回移动,那么你的程序很容易就会移动并转换大量的像素数据。

同样,许多图层可能会消耗大量的内存。

我只在这里看到一半的谈话,所以我可能会误解。 根据我最近的经验,优化CALayer渲染,并调查苹果的做法(不)优化的东西,你会期望优化…

如果这一切都结束了caching和扁平化,有什么区别?

苹果最终每层创build一个单独的GPU元素。 如果你有很多图层,你有很多的GPU元素。 如果你有一个drawRect,你只有一个元素。 苹果公司往往不扁平化,即使他们可以(也可能“应该”)。

在很多情况下,“很多元素”是没有问题的。 但是,如果它们变得很大…或者它们已经足够了……或者它们对于OpenGL来说尺寸不合适……并且(见下文)它们被存储在CPU而不是GPU上,那么事情就会变得糟糕。 NB:以我的经验:

  • “足够”:40+在内存中
  • “大”:100×100点(200×200视网膜像素)

苹果公司的GPU元素/缓冲区代码在大多数地方都得到了很好的优化,但在less数几个地方,它的优化程度非常低。 性能下降就像是要跳下悬崖。

另外,如果您正在处理单元重用,则不必在每次调用-cellForRowAtIndexPath时重新生成视图

你说“正确”,除了…… IIRC苹果公司的文件告诉人们不要这样做,他们会采取一个更简单的方法(恕我直言:弱文档),而是重新填充每个电话的所有子视图。 在哪一点…你有多less钱?

最后:

…并不是所有这些与iOS 6,其中创build一个UIView的成本大大降低的变化? (我还没有介绍过,刚刚从其他开发者那里听说过)