1

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

到目前为止,在我的代码中,我对XROpenGL类的实例方法进行了大约 1100 次调用,renderSprite(XRSprite)该方法是一个重载方法,renderSprite(XRSprite,int,int,int)该方法又调用不少于五个其他方法,其中许多方法从XRSprite. 你可以想象,有很多消息被发送。

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

4

1 回答 1

3

那是每帧 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 函数吗?

显然是的,你可以用 C++ 重写关键代码。但是对于中级绘图代码,您不必这样做;C++ 通常留给低级构造,如向量和四元数以及其他此类原语。

于 2012-12-24T17:14:40.550 回答