Objective-C中的消息发送成本

U62*_*U62 5 iphone objective-c

我很想知道在各种情况下Objective-C中的消息发送成本.特别是我想指导我选择的程序设计,所以我不想通过避免消息发送来过早优化,因为它们可以实现更好的设计.

我当前项目中的一个案例是我有一个带有实例变量的类:offsetX和offsetY.我经常想要绝对偏移量,目前我在这个地方都有这行代码: -

int absOffset = ((offsetX < 0.0) ? -offsetX : offsetX) + 
                 ((offsetY < 0.0) ? -offsetY : offsetY);
Run Code Online (Sandbox Code Playgroud)

现在,如果这是C++,我将创建一个返回absOffset值的内联函数.即使在Java/C#中,我也可以将这样的函数定义为final/sealed,并且非常确定它将被内联.

目标-C将是: -

-(int)absOffset {
    return ((offsetX < 0.0) ? -offsetX : offsetX) + 
            ((offsetY < 0.0) ? -offsetY : offsetY);
}
Run Code Online (Sandbox Code Playgroud)

我会这样称呼它: -

int ao = [self absOffset];
Run Code Online (Sandbox Code Playgroud)

现在,编译器能够内联吗?我假设它至少能够将它修复为直接函数调用并避免动态消息调度(我假设)objective-c必须使用因为它的类型系统.

另外,一般来说,客观C中的消息调度成本是多少?通过'id'调用指向具体类的指针时,它是否有所不同?

Zif*_*fre 14

Objective C消息非常快.速度与C++虚拟方法调用相当,但速度不是很快.避免消息传递绝对是不成熟的优化.您可能不希望在内部循环中执行大量操作,但您选择的算法和其他因素将对代码的速度有更大的影响.如果它太慢,请使用分析器并从那里开始.

  • +1.值得指出的是,消息传递代码都是用高度优化的汇编代码编写的,它位于:http://opensource.apple.com/source/objc4/objc4-371.2/runtime/Messengers.subproj/ (6认同)
  • 根据发布的链接,虚拟函数调用需要1.1ns,而Objective-C调度需要4.9ns - 这几乎慢了5倍.据称,尽管调度员在适当的情况下仍然会受到相当大的打击.我绝对同意避免过早优化! (4认同)

phi*_*red 5

首先,我将使用C函数fabs().对于其他一些简单的内联函数来说,小函数的辅助函数可以很好地工作.使用方法而不是谨慎的行为可能是糟糕设计的标志.性能甚至还没有进入.

接下来,编译器无法优化方法调用.它是一种动态语言,直到运行时才调用该调用.各种Objective-C技术可能会破坏编译器的任何尝试.

调用"id"上的方法与类型指针之间在运行时没有区别 - 它们通过完全相同的机制.

最后,如果您在测量之前考虑性能特征,那么您已经过早地进行了优化.这并不是说这种情况永远不合适,因为有些人可能会相信,但它通常都适用.在这种情况下,我认为,如果你把设计放在首位,你可能最终会得到一个足够好的性能配置文件.必要时,稍后进行测量和优化.