在Objective-C中使用异常的成本是多少?

时间:2010-09-10 09:15:36

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

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

C ++和Java人总是告诉我,除非抛出异常,否则异常不会花费任何性能。 Objective-C也是如此吗?

2 个答案:

答案 0 :(得分:9)

  

C ++和Java人总是告诉我,除非抛出异常,否则异常不会花费任何性能。 Objective-C也是如此吗?

简答

仅适用于64位OS X和iOS。

他们并非完全自由。更准确地说,该模型经过优化,可以在常规执行期间最大限度地降低成本(在其他地方产生影响)。

详细答案

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

在64位OS X中,ObjC转而借用C ++的“Zero Cost Exceptions”。零成本异常具有非常低的执行开销,除非抛出。零成本例外有效地将执行成本转移到二进制大小。这是他们最初未在iOS中使用的主要原因之一。启用C ++异常和RTTI可以将二进制大小增加50%以上 - 当然,我认为纯粹的ObjC中这些数字要低得多,因为在展开时执行的数量较少。

在arm64中,异常模型已从Set Jump Long Jump更改为Itanium派生的Zero Cost Exceptions(根据程序集判断)。

然而,惯用的ObjC程序没有编写或准备从异常中恢复,因此您应该保留它们用于您不打算从中恢复的情况(如果您决定使用它们) )。 Clang manual on ARC以及引用页面的其他部分中的更多详细信息。

答案 1 :(得分:6)

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

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

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