views:

709

answers:

2

I'm curious to know about the cost of message dispatch in Objective-C in various situations. Particularly I want to guide my choice of program design so I'm not tempted to prematurely optimize by avoiding message dispatches when they would make for a better design.

A case in my current project is that I have a class with instance variables: offsetX and offsetY. I often want the absolute offset and at the moment I have this line of code all over the place:-

int absOffset = ((offsetX < 0.0) ? -offsetX : offsetX) + 
                 ((offsetY < 0.0) ? -offsetY : offsetY);

Now if this was C++ I would create an inline function that returned the value for absOffset. Even in Java/C# I could define such a function as final/sealed and be pretty sure it would be inlined.

The objective-C would be:-

-(int)absOffset {
    return ((offsetX < 0.0) ? -offsetX : offsetX) + 
            ((offsetY < 0.0) ? -offsetY : offsetY);
}

and I would call it like so:-

int ao = [self absOffset];

Now, is the compiler able to inline that? I assume it is able at least fix it to a direct function call and avoid the dynamic message dispatch that (I assume) objective-c must use because of it's type system.

Also, in general, how much does message dispatch cost in objective-C? Does it differ when calling through an 'id' versus a pointer to a concrete class?

+5  A: 

Objective C messages are very fast. The speed is comparable to C++ virtual method calls, although not quite as fast. Avoiding message passing is definitely premature optimization. You might not want to do a lot of it in an inner loop, but the algorithms you choose and other factors will have a much bigger factor on how fast your code is. If it is too slow, use a profiler and go from there.

Zifre
+1. It's worth pointing out that the messaging code is all written in highly-optimised assembly code, which is located here: http://opensource.apple.com/source/objc4/objc4-371.2/runtime/Messengers.subproj/
Jim Dovey
I'm scratching my head at Mike Ash's numbers for op costs. I ran a similar measurement of C++ virtual call overhead, and the time I got for each virtual indirect on a 3.3GHz processor was more like 7ns than his 1.
Crashworks
According to the link posted a virtual function call takes 1.1ns while an Objective-C dispatch takes 4.9ns -- which is almost 5x slower. As fast as the dispatcher is purported to be that can still be quite a hit in the right circumstances. I definitely agree about avoiding premature optimization!
fbrereto
+2  A: 

First, I'd use the C function, fabs() for this. For other things writing simple, inline, C functions for little helper cases can work well. Using methods for convenience rather than discreet behaviour can be a sign of bad design. Performance doesn't even come into it yet.

Next, the compiler cannot optimise a method call away. It's a dynamic language, the call is not resolved until runtime. Various Objective-C techniques could defeat any attempt of the compiler to do so.

There is no difference at runtime between calling a method on an "id" vs a typed pointer - they go through exactly the same mechanism.

Finally, if you're thinking about the performance characteristics before measuring you are already prematurely optimising. That's not to say that is never appropriate, as some might have you believe, but it does usually hold true. In this case, I think, if you put the design first you'll probably end up with a decent enough performance profile anyway. Measure and optimise later, as necessary.

Phil Nash
Could you address some techniques to reduce cost of messaging mechanism (dynamic dispatch) in Objective-C?
Eonil
There's not really much you can do to reduce its cost, per se. It's a fixed mechanism, and is pretty well optimised already. There are things to bear in mind, tho - such as not using methods when C helper functions are more appropriate (as per my post above), avoiding boxing and unboxing where you can, and just good general design principles. If the cost of message passing is really a bottleneck (hint it very rarely is), then maybe Obj-C is not the right tool. You can mix C++ with Objective-C (Objective-C++) quite easily, for example.
Phil Nash