Objective-C运行时性能惩罚的细节

时间:2011-04-20 23:43:05

标签: objective-c c performance

我一直在尝试使用Objective-C(特别是GNU运行时,我没有使用GNUStep或类似的东西)来扩展C对象。到目前为止一切顺利 - 它运行良好,我非常喜欢语法,但是从我读过的内容来看,使用Objective-C对象会对性能造成影响。

我通常不会过早地进行优化,但我正在开发一款游戏,所以性能最终会变得非常关键 - 我想知道自己要做些什么!有几个人建议我在游戏中使用Objective-C会很好,只要我的内部循环用标准C编写,但问题是找到我应该进行切换的地方。

所以我的问题有两个:

  • 究竟会导致性能下降? (所以我知道应该避免的事情)
  • 粗略这种性能损失有多重要? (所以我可以提前猜测我的游戏中哪些部分需要用C编写)

我的猜测是,在Objective-C对象上调用方法会产生一些惩罚,但我不确定还会有什么 - 取消引用Objective-C对象会产生类似的惩罚吗?

int a = myobj->a;

使用try-catch-finally怎么样?在没有抛出异常的情况下,这会导致性能下降吗?

我意识到在某种程度上我可以用基准测试来解决大部分问题,但我对此相对较新,我希望更深入地了解Objective-C的工作原理以及任何性能惩罚的性质

我目前对C ++不感兴趣,我只是在试验Objective-C。

2 个答案:

答案 0 :(得分:5)

  

所以我的问题有两个:

     

究竟会导致性能下降? (所以我知道应该避免的事情)

     

这种性能损失大致有多重要? (所以我可以提前猜测我的游戏中哪些部分需要用C编写)

(我的基础来自苹果公司的实施:)

在大多数情况下,最大的损失是每个实例方法(消息传递)都是动态调用

此呼叫/消息的成本大约是c ++虚拟呼叫的4倍。

这些调用可能没有被优化掉(除非有人对JIT / HotSpot做了很好的实现),并且这些方法与c或c ++不同,可能没有内联。

但不仅仅是消息传递:

您的对象将被重新计算分配。这意味着:大量的锁定和许多单独的小分配,以及用于引用计数的原子。

objc_msgSend和变体(运行时消息传递实现的核心)可以采用,比如单独执行时间的10%(极端真实世界的情况)。

它也可以添加到二进制大小。

习惯用法在很多方面推动c ++或c的速度。 (例如,考虑如何传递/处理数字)。

您需要多少费用取决于您的方法的大小。好的ood意味着你的方法通常很短。你要么会得到很多信息和明显的重量(如果是高性能),要么会损害你的设计。

还有其他一些问题,比如实时应用程序。

  

int a = myobj-> a;

与c相比没有差异

  

... ...例外

(iirc)apple以前的异常模型过去常常使用昂贵的设置,现在它们与c ++的零成本异常一致(优化了异常不会被定期抛出,并且在进入/设置时是边缘的,但​​抛出/捕获是昂贵的)。

如果性能非常重要,我会避免使用c ++。它有很多功能和速度。你需要做一些工作才能获得objc的一些便利 - 大部分都在于可用的库,而不是语言。

答案 1 :(得分:3)

如果我是你,我会编写一个原型,给它一个真实的工作量,然后找出它的哪些部分是问题。 Here's an example of what I mean.

换句话说,你可以得到答案,告诉你某某是“有效”或“效率低下”,但它是否真的适用于你的情况是一个完整的WAG。 所以要做的就是尝试它,让程序本身告诉你哪些部分需要更好的东西。