【问题标题】:What is the cost of using exceptions in Objective-C?在 Objective-C 中使用异常的成本是多少?
【发布时间】:2011-04-10 15:39:07
【问题描述】:

我的意思是在当前的 clang 实现或 gcc 版本中。

C++ 和 Java 的人总是告诉我,除非抛出异常,否则它们不会消耗任何性能。 Objective-C 也一样吗?

【问题讨论】:

  • 我很确定 C++ 人通常会告诉您,除非抛出异常,否则异常的成本可以忽略不计

标签: objective-c performance cocoa exception error-handling


【解决方案1】:

C++ 和 Java 的人总是告诉我,除非抛出异常,否则它们不会消耗任何性能。 Objective-C 也一样吗?

简答

仅适用于 64 位 OS X 和 iOS。

它们并非完全免费。更准确地说,该模型经过优化,以最大限度地降低常规执行期间的成本(将后果转移到其他地方)。

详细解答

在 32 位 OS X 和 iOS 上,即使没有抛出异常,也会产生运行时成本。这些架构不使用零成本异常。

在 64 位 OS X 中,ObjC 借用了 C++ 的“零成本异常”。零成本异常的执行开销非常低,除非被抛出。零成本异常有效地将执行成本转变为二进制大小。这是它们最初没有在 iOS 中使用的主要原因之一。启用 C++ 异常和 RTTI 可以将二进制大小增加 50% 以上——当然,我希望这些数字在纯 ObjC 中要低得多,因为展开时要执行的操作更少。

在 arm64 中,异常模型从 Set Jump Long Jump 更改为 Itanium 衍生的零成本异常(由程序集判断)。

但是,惯用的 ObjC 程序并未编写或准备从异常中恢复,因此您应该将它们保留用于您不打算从中恢复的情况(如果您决定使用它们) )。 Clang manual on ARC 和参考页面的其他部分中的更多详细信息。

【讨论】:

  • 另外,您应该指出异常导致 ARC 的问题:clang.llvm.org/docs/AutomaticReferenceCounting.html - “默认情况下使代码异常安全将对通常实际上并不关心的代码施加严重的运行时和代码大小惩罚关于异常安全性。因此,ARC 生成的代码默认会在异常上泄漏,如果进程将立即终止,这很好。"
  • @BradLarson 很好的参考——感谢 +1,并添加了。可能值得注意的是, 在执行时真正特定于 ARC 的唯一部分是:“ARC 确实会在异常终止其范围时结束 __weak 对象的生命周期,除非禁用异常在编译器中。”.链接的描述当然有助于限定为什么在 ObjC 程序中无法(可靠地,以明确定义的方式)恢复异常的示例。
  • 这对我来说很好。希望他们保持这种状态 :-) 作为 Eiffel 程序员,我讨厌异常并且非常有限地使用它们。
  • @justin,谢谢你的回答!请问64位iOS是否支持“零成本异常”?
  • @FreeNickname 更新了答案。感谢您指出需要更新。
【解决方案2】:

根据 Mac OS X v10.5 中的 Objective-C 运行时的一些 2007 发行说明,他们重新编写了 Objective-C 异常的 64 位实现,以提供“零成本”的 try 块和与 C++ 的互操作性。

显然,这些“零成本”的 try 块在进入 try 时不会产生时间损失,这与必须调用 setjmp() 和其他函数的 32 位对应块不同。显然扔掉它们“要贵得多”。

这是我可以在 Apple 的发行说明中找到的唯一信息,因此我不得不假设这仍然适用于今天的运行时,因此,32 位异常 = 昂贵,64 位异常 = “零成本”

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-20
  • 2011-06-06
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 2013-06-27
  • 2016-05-09
相关资源
最近更新 更多