【发布时间】:2011-04-10 15:39:07
【问题描述】:
我的意思是在当前的 clang 实现或 gcc 版本中。
C++ 和 Java 的人总是告诉我,除非抛出异常,否则它们不会消耗任何性能。 Objective-C 也一样吗?
【问题讨论】:
-
我很确定 C++ 人通常会告诉您,除非抛出异常,否则异常的成本可以忽略不计。
标签: objective-c performance cocoa exception error-handling
我的意思是在当前的 clang 实现或 gcc 版本中。
C++ 和 Java 的人总是告诉我,除非抛出异常,否则它们不会消耗任何性能。 Objective-C 也一样吗?
【问题讨论】:
标签: objective-c performance cocoa exception error-handling
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 和参考页面的其他部分中的更多详细信息。
【讨论】:
__weak 对象的生命周期,除非禁用异常在编译器中。”.链接的描述当然有助于限定为什么在 ObjC 程序中无法(可靠地,以明确定义的方式)恢复异常的示例。
根据 Mac OS X v10.5 中的 Objective-C 运行时的一些 2007 发行说明,他们重新编写了 Objective-C 异常的 64 位实现,以提供“零成本”的 try 块和与 C++ 的互操作性。
显然,这些“零成本”的 try 块在进入 try 时不会产生时间损失,这与必须调用 setjmp() 和其他函数的 32 位对应块不同。显然扔掉它们“要贵得多”。
这是我可以在 Apple 的发行说明中找到的唯一信息,因此我不得不假设这仍然适用于今天的运行时,因此,32 位异常 = 昂贵,64 位异常 = “零成本”
【讨论】: