【问题标题】:Specifics of Objective-C runtime performance penaltiesObjective-C 运行时性能损失的细节
【发布时间】:2011-04-20 23:43:04
【问题描述】:

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

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

所以我的问题是双重的:

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

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

int a = myobj->a;

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

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

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

【问题讨论】:

标签: objective-c c performance


【解决方案1】:

所以我的问题是双重的:

究竟什么会导致性能损失? (所以我知道我应该避免什么)

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

(我的苹果实现的基础:)

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

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

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

但不仅仅是消息传递:

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

objc_msgSend 和变体(运行时消息传递实现的核心)可能仅占用 10% 的执行时间(极端现实世界的情况)。

它也可以增加二进制大小。

惯用用法使其在许多领域的速度比 c++ 或 c 的速度更进一步。 (例如,考虑如何传递/处理数字)。

花费多少取决于方法的大小。好 ood 意味着您的方法通常会很短。您最终会收到大量消息和显着的重量(如果要实现高性能),或者会影响您的设计。

还有一些其他的陷阱,比如在实时应用中。

int a = myobj->a;

与 c 相比没有差异

...例外情况...

(iirc) 苹果以前的异常模型过去使用昂贵的设置,现在它们沿着 c++ 的零成本异常的路线(优化了异常不会定期抛出,并且在进入/设置时边缘化,但抛出/捕获成本很高)。

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-11-25
      • 2019-02-09
      • 1970-01-01
      • 2012-11-18
      • 2017-07-27
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 2011-11-22
      相关资源
      最近更新 更多