August 01, 2005

Objective-C messaging

Peter has some interesting thoughts about objc_msgSend. His post is worth reading if you're curious about some complicated ways to improve performance, but there's one important thing missing: This shouldn't be necessary for nearly all developers.

Premature optimization is almost always a bad idea. I'm a bit concerned that folks will read Peter's post and think, "objc_msgSend is slow! Hey, I use Objective-C! I can make my code a lot faster by tweaking my compiler!" Bad idea. The reason why objc_msgSend spends a third of its time in the dyld stub (at least for Peter's test) is that objc_msgSend is really fast. Lots of people have spent lots of time over the years making it as fast as it can possibly be. (Which isn't to say that it can't be faster...feel free to grab the code and see if you can improve it without breaking binary compatibility.)

In other words, if your application has performance problems in certain areas, chances are it isn't due to objc_msgSend. Measure your application's performance with Shark, and in the unlikely event that a specific algorithm is spending too much time in objc_msgSend, there are two simple solutions that can help:

  • Rewrite your algorithm (not your whole application) to not use Objective-C messaging. If you're using Objective-C, you're using a dynamic language. The dynamism is great, and Apple's implementation is phenomenally fast for a dynamic language, but it just won't be as fast as C.

  • In a local variable, grab a function pointer to objc_msgSend, grab your selector in another variable, and call the object and selector through your function pointer. This is similar to what Peter described, but it's much more common, doesn't involve changing the compiler, and doesn't have the overhead of using a global variable.

Again, though, the need for this is exceedingly rare. If your application already performs fine for your users, you're much better off spending your time making it a better application than tweaking it so the frobnaz can blindle in six microseconds instead of nine microseconds. Making your frobnaz that much faster may sound cool, but really it's a waste of your time.