我很想知道在各种情况下Objective-C中的消息发送成本。特别是我想指导我选择的程序设计,所以我不想过早地通过避免消息发送进行优化来实现更好的设计。
我当前项目中的一个案例是我有一个带有实例变量的类:offsetX和offsetY。我经常想要绝对偏移量,此刻我在这个地方都有这行代码: -
int absOffset = ((offsetX < 0.0) ? -offsetX : offsetX) +
((offsetY < 0.0) ? -offsetY : offsetY);
现在如果这是C ++,我会创建一个返回absOffset值的内联函数。即使在Java / C#中,我也可以将这样的函数定义为final / sealed,并且非常确定它将被内联。
目标-C将是: -
-(int)absOffset {
return ((offsetX < 0.0) ? -offsetX : offsetX) +
((offsetY < 0.0) ? -offsetY : offsetY);
}
我会这样称呼: -
int ao = [self absOffset];
现在,编译器能够内联吗?我假设它至少可以将它修复为直接函数调用,并避免动态消息调度(我假设)objective-c必须使用因为它的类型系统。
另外,一般来说,目标C中的消息调度费用是多少?通过'id'和指向具体类的指针调用它有什么不同?
答案 0 :(得分:14)
Objective C messages are very fast.速度与C ++虚拟方法调用相当,但速度不是很快。避免消息传递肯定是过早优化。您可能不希望在内部循环中执行大量操作,但您选择的算法和其他因素将对代码的速度有更大的影响。如果它太慢,请使用分析器并从那里开始。
答案 1 :(得分:5)
首先,我将使用C函数fabs()。对于其他一些简单的内联函数来说,小函数的辅助函数可以很好地工作。使用方法而不是谨慎的行为可能是糟糕设计的标志。表现甚至还没有进入。
接下来,编译器无法优化方法调用。它是一种动态语言,直到运行时才调用该调用。各种Objective-C技术可能会破坏编译器的任何尝试。
在“id”与类型指针之间调用方法时,运行时没有区别 - 它们完全采用相同的机制。
最后,如果您在测量之前考虑性能特征,那么您已经过早地进行了优化。这并不是说从不是合适的,因为有些人可能会相信,但它通常都是正确的。在这种情况下,我认为,如果你把设计放在首位,你可能最终会得到一个足够好的性能配置文件。必要时,稍后进行测量和优化。