4 ms·
> Objective-C doesn't use methods like Java/C++/C#, it uses messages like Smalltalk. This effectively means it always performs late binding and invoking a messa
by kybernetyk 13y ago
> Objective-C doesn't use methods like Java/C++/C#, it uses messages like Smalltalk. This effectively means it always performs late binding and invoking a message is REALLY slow in Objective-C.
Well, "always" is a little wrong. The first time a message is passed and the bound method is called by the runtime is significantly slower (~4x slower than a virtual method call in C++). But then this message/method pair gets cached and for every subsequent call the cache is used.
Then there's some real neat trickery that is performed in objc_msgSend() ... after the method to "call" has been found the code directly jumps into that method without creating a new stack frame. (All needed arguments have been passed to objc_msgSend() and are already on the stack.) objc_msgSend() in essence is a trampoline.
So when sending a message to an object multiple times you only pay for the cache lookup - which is pretty fast by itself and a cached call is faster than a C++ virtual method call.
Performance Numbers: http://www.mikeash.com/pyblog/performance-comparisons-of-common-operations-leopard-edition.html http://www.mikeash.com/pyblog/performance-comparisons-of-com...
More about objc_msgSend(): http://www.mikeash.com/pyblog/friday-qa-2012-11-16-lets-build-objc_msgsend.html http://www.mikeash.com/pyblog/friday-qa-2012-11-16-lets-buil...
Now I don't know enough about Java but I guess it isn't much more faster than that. So calling Obj-C slow may be a little too bold.
- invalidname 13y agoMaybe this Objective-C optimization isn't implemented in iOS: http://www.shannah.ca/blog/?p=226 http://www.shannah.ca/blog/?p=226
- kybernetyk 13y agoIt really isn't that big of a deal. Trampolining is pretty straight forward and a caching of memory addresses isn't a big deal either. So I don't know why Apple wouldn't add this optimization to the iOS obj-c runtime.
- asveikau 13y agoTrampolining is harder to do if you keep around this absurdity (sorry "security feature") of not being able to mark pages as executable. If they open this up for the objc runtime then any other code in the same process would be able to do it too.
- pbsdp 13y agoYou're assuming writable trampolines. objc_msgSend()'s trampoline works by caching the target lookup and having an extremely short fast-path in the case that the target method implementation is cached. objc_msgSend is a trampoline in the sense that it leaves the frame/registers untouched and jumps straight to the target implementation. That said, you can implement the kinds of trampolines you're referring to without writable code pages, it just requires more work: http://landonf.bikemonkey.org/2011/04/index.html http://landonf.bikemonkey.org/2011/04/index.html
- pkolaczk 13y agoJava can inline many of virtual calls, making them essentially as fast as static methods (= much faster than C++ virtual methods).
- rsynnott 13y agoThough, while Java can, it looks like Dalvik generally does not (though, most of the info available seems to be 2.3-era; possibly things have improves since). It looks like 2.3 Dalvik can inline getters and setters, but it's certainly no Hotspot.
- Zigurd 13y agoDalvik is designed around criteria that are nearly diametrically opposed to those for Hotspot. Hotspot goes for maximum performance. Dalvik's JIT compiler is designed for maximum impact on performance with minimum computation. In other words, Dalvik's JIT is designed for battery powered devices.
- rsynnott 13y agoOh, sure, I absolutely realise that a very aggressive JIT wouldn't be ideal for Dalvik. However, given that the article is talking about how wonderful JIT is, it perhaps concentrates a little too much on all the wonderful JIT things that Dalvik (the only mobile JIT of serious interest to most developers) does not do.
- invalidname 13y agoSince the article was written by a Sun guy Dalvik is probably not the area of expertise there...
- buza 13y agoDepends on what you mean by 'Hotspot'. Both of Sun's embedded JVMs (CDC, CLDC) had 'Hotspot' implementations. Both of these implementations performed many of these types of optimizations (which I can say with certainty because I wrote many of them). I'm no Dalvik expert, but there really isn't any reason why it shouldn't be able to do similar optimizations. Remember that the CDC and CLDC Hotspot implementations were originally developed for hardware of the early 2000s.
- js2 13y agoAnother good discussion of objc_msgSend() is: http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/ http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-th...
- kybernetyk 13y agoAh yeah, that's the article(s) I wanted to link here but couldn't find anymore. A very good read!
- cwzwarich 13y ago> So when sending a message to an object multiple times you only pay for the cache lookup - which is pretty fast by itself and a cached call is faster than a C++ virtual method call. This is not true. The code in Mike's test for "IMP-cached message send" doesn't match the cached path of objc_msgSend. It matches what you would get by doing IMP-caching yourself, which is common in some Objective-C frameworks, especially older ones. The cached path of objc_msgSend is what is measured by the "Objective-C message send" row, which is a lot slower. The fast path of objc_msgSend roughly goes like this: you dereference the isa of the object to get to a class description, then you dereference a pointer to the cache, and after finding the selector in the cache, perform a tail indirect call to the IMP. Even if the cache lookup is free this is two dependent pointer dereferences followed by a dependent indirect branch. A C++ virtual call just dereferences a vptr and makes an indirect call to a function at a static index in the vtable, which will always be more efficient than objc_msgSend. It's true that manually caching the IMP yourself and calling it will be faster than a C++ virtual call, but there's nothing stopping you from caching the implementation of a C++ virtual call in exactly the same way. Another major factor in the performance difference between C++ and Objective-C is that C++ allows you to have non-virtual member functions, which can be inlined, whereas Objective-C requires all method calls to go through the same mechanism.
- deleted 13y ago[deleted]