A simple array index is quite a bit faster than
objc_msgSend, even with its fancy caching and finely tuned assembly code, so this is a nice performance win.
The call to
testmethod2is even nicer. Because it’s declared
@final, the compiler knows that nothing can override it. No matter what happens, the call will always go to the implementation in
Class. Thus the compiler doesn’t even need to emit a vtable lookup. It can just make a normal function call that goes straight to
__TFC9speedtest5Class11testmethod2fS0_FT_T_, which is the mangled name of the testmethod2 implementation in my test case.
The different method call semantics allow speed improvements beyond simply using faster dispatch techniques. Because the compiler can better understand where control goes, it can optimize the code better. It can potentially inline method calls or even eliminate them entirely.
Swift omits the
_cmdparameter, freeing up an additional argument register for more useful purposes. For methods that take several explicit parameters (three or more for ARM, five or more for x86-64, and seven or more for ARM64), this means a small performance win on every call due to better use of argument registers.
Stay up-to-date by subscribing to the Comments RSS Feed for this post.