views:

308

answers:

3

I've been making some progress with audio programming for iPhone. Now I'm doing some performance tuning, trying to see if I can squeeze more out of this little machine. Running Shark, I see that a significant part of my cpu power (16%) is getting eaten up by objc_msgSend. I understand I can speed this up somewhat by storing pointers to functions (IMP) rather than calling them using [object message] notation. But if I'm going to go through all this trouble, I wonder if I might just be better off using C++.

Any thoughts on this?

+9  A: 

Objective C is absolutely fast enough for DSP/audio programming, because Objective C is a superset of C. You don't need to (and shouldn't) make everything a message. Where performance is critical, use plain C function calls (or use inline assembly, if there are hardware features you can leverage that way). Where performance isn't critical, and your application can benefit from the features of message indirection, use the square brackets.

The Accelerate framework on OS X, for example, is a great high-performance Objective C library. It only uses standard C99 function calls, and you can call them from Objective C code without any wrapping or indirection.

Stephen Canon
Thanks Stephen. If I want to code audio in an object-oriented way, seems like Obj-C may be not help me much though. If I want modular, pluggable components and don't want to do acrobatics to call methods on my objects, seems like C++ may suit my needs better.
morgancodes
@morgancodes: In most high-performance codes that I've encountered, modularity happens at a relatively high-level, not at the level of each and every function call. There's nothing stopping you from having high-level modular pluggable components using Objective-C message dispatch whose core low-level implementations use C function calls. If that really isn't possible in your situation, but C++ virtual function lookup overhead *is* somehow acceptable, then I suppose you should use C++. That seems like a pretty narrow situation, however.
Stephen Canon
+1  A: 

The problem with Objective-C and functions like DSP is not speed per se but rather the uncertainty of when the inevitable bottlenecks will occur.

All languages have bottlenecks but in static linked languages like C++ you can better predict when and where in the code they will occur. In the case of Objective-C's runtime coupling, the time it takes to find the appropriate object, the time it takes to send a message is not necessary slow but it is variable and unpredictable. Objective-C's flexibility in UI, data management and reuse work against it in the case of tightly timed task.

Most audio processing in the Apple API is done in C or C++ because of the need to nail down the time it takes code to execute. However, its easy to mix Objective-C, C and C++ in the same app. This allows you to pick the best language for the immediate task at hand.

TechZen
Thanks TechZen. I think it may be time for me to move more into C++ land.
morgancodes
A: 

objc_msgSend is just a utility. The cost of sending a message is not just the cost of sending the message. It is the cost of doing everything that the message initiates. (Just like the true cost of a function call is its inclusive cost, including I/O if there is any.)

What you need to know is where are the time-dominant messages coming from and going to and why. Stack samples will tell you which routines / methods are being called so often that you should figure out how to call them more efficiently.

You may find that you're calling them more than you have to.

Especially if you find that many of the calls are for creating and deleting data structure, you can probably find better ways to do that.

Mike Dunlavey
Thanks Mr. Dunlavey. Let me make sure I'm not confused though. When I profile my code in shark, and I see "15%" next to objc_msgSend, that looks like an opportunity for optimization to me. I believe that 15% is the actual expense of sending the message, not executing the code that the message initiates. Correct? So in a tight loop, I can indeed gain some performance by avoiding objc_msgSend, right?
morgancodes
Mike Dunlavey
@morgancodes: Shark says it takes 10,000 samples over 10 sec. Suppose a line of code is on the stack 20% of the time, so removing it could save that overall time. If you take 20 samples, then you will see it on 20%(4) of the samples, give or take 9%(1.8). If 10,000 samples are taken, the line will show up 20% (2000) of the samples, give or take 0.4% (40). Either way, will you miss it? Problem with Shark is it gives you needless precision but doesn't give you the insight you get by looking at specific samples.
Mike Dunlavey
Hmmm. The debugger in XCode isn't giving me a useful call stack. I also don't get any useful profiling info out of instruments, have to use Shark. I suspect this has something to do with the fact that all of my audio code get called by a c callback from an audio unit, rather from the iPhone's main run loop. So, I'll look in to that and then try your idea.
morgancodes