减少objc_msgSend并保留/释放调用

时间:2012-12-24 11:57:55

标签: objective-c ios cocoa-touch

在Objective-C中调用方法/属性的性能开销正在扼杀我的iOS应用程序的性能; Xcode探查器(又名,Instruments)将70%的延迟归因于objc_msgSend_retain_release

在我的代码中,到目前为止,我对XROpenGL类的实例方法renderSprite(XRSprite)进行了大约1100次调用,这是renderSprite(XRSprite,int,int,int)的重载方法,后者又调用了不少于5个其他方法方法,其中许多方法来自XRSprite的访问属性。可以想象,发送的消息很多。

除了用C ++重写代码的关键部分外,我还有其他选择吗?

1 个答案:

答案 0 :(得分:2)

每帧有6,600个电话吗?为了便于讨论,我将假设为60 FPS,总呼叫数为396,000,仅用于显式方法调用。如果你假设悲观情况,objc_msgSend的开销(相对于C函数调用)仍然只有O(100)个周期。所以在现代的iDevice上,你只需要大约4%的CPU时间。没什么大不了的。您可能会为每次调用获得一个或两个相应的版本,但保留/释放相对较快,因此我们再次讨论单位数百分比。这种性质的“运行时开销”高达~10%并不被认为是恶劣的,一般来说,虽然它不是最佳的。

所以,我给你的问题是:

  1. 你能发布你的代码吗?
  2. 您是否可以发布更详细的个人资料信息(例如,各种前10种方法之间的确切细分,以及主要方法的调用堆栈)?
  3. 你确定时间实际上花在objc_msgSend等人身上,而不仅仅是在孩子身上吗?
  4. 你真的打了几个电话?如在测量中,没有假设。
  5. 您可以使用ivars而不是@properties来删除一些方法调用吗?
  6. 沿着这些方向,您是否在一种方法中多次使用它们时缓存您访问的属性?
  7. 你可以重构以减少方法调用的数量,和/或使用vanilla C函数来处理某些事情吗?
  8. 显然是的,您可以在C ++中重写密钥代码。但对于中级绘图代码,您不应该这样做; C ++通常留给低级构造,如向量和四元数以及其他类似的原语。