3 ms·
> 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+
by 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.