views:

195

answers:

2

Hello Stackoverflow.

I have written an application that has a number of custom views and generally draws a lot of lines and bitmaps. Since performance is somewhat critical for the application, I spent a good amount of time optimizing draw performance.

Now, activity monitor tells me that my application is usually using about 12% CPU and Instrument (the profiler) says that a whopping 10% CPU is spent in objc_msgSend (mostly in drawing related system calls).

On the one hand, I am glad about this since it means that my drawing is about as fast as it gets and my optimizations where a huge success. On the other hand, it seems to imply that the only thing that is still using my CPU is the Objective-C overhead for messages (objc_msgSend). Hence, that if I had written the application in, say, Carbon, its performance would be drastically better.

Now I am tempted to conclude that Objective-C is a language with bad performance, even though Cocoa seems to be awfully efficient since it can apparently draw faster than Objective-C can send messages.

So, is Objective-C really a language with bad performance? What do you think about that?

+7  A: 

No, Objective-C's performance is not that bad. For evidence, I cite @bbum's series of articles on the hand-optimized assembly of objc_msgSend:

  1. The Roadmap
  2. Setting the Stage
  3. The Fast Path
  4. Method Lookup and some odds and ends

In other words, objc_msgSend is fast; method dispatch is not your problem. Can you post your profiling information that leads you to believe otherwise? It's possible that you're misreading the analysis, or that you're doing something really strange under the covers, etc.

But I guarantee you that objc_msgSend is not the problem. If it was, we surely would've heard about it by now. :)

Dave DeLong
It wouldn't surprise me at all if the program is spending 10% of its time in obj_msg_send. I've seen much higher percentages. I wrote a 6502 emulator in Objective C and was seeing time in obj_msg_send of the order of 20% or more. Compared to a C function call obj_msg_send is expensive, but on the other hand rewriting even my 6502 emulator in pure C would gain only 20%. As it happens I was able to gain a lot with simple obvious optimisations like: `for (i = 0; i < [array count] ; ++i)` => `size_t arrayCount = [array count] ; for (i = 0 ; i < arrayCount...`
JeremyP
+2  A: 

Which way around are you viewing the call Tree (see the checkbox marked "Invert Call Tree")?

If you have the call stack inverted, have you drilled down into objc_msgSend to see where the time is spent?

The "Running Time %" that is shown by default (cntrl-click to change) means 'percentage of time your code was busy' - eg. if you run 1 short fast method and then idle for 10 hours the percentage time for your method, and therefore for objc_msgSend because that is the method that called your method - would be %100 - That doesn't mean that objc_msgSend is slow.

mustISignUp
As I said, the time is mostly spent in drawing related calls. But that still means that drawing speed is mostly limited by objc_msgSend, doesn't it?
BastiBechtold
No no, it doesn't mean that at all. Say, you see 'objc_msgSend 10%' and you drill down into that and you see inside objc_msgSend '-init 3.33%', '-drawRect 3.33%', 'dealloc 3.33%' that's your 10% right there, taken up by your methods, so the overhead of the objc_msgSend was zero (in reality close to zero). The fact that you are using 12% of the cpu means that you are idling for %88 of the time (if you have 1 core, 188% if you have 2 cores etc.) so you are not actually being limited at all - you are not coming anywhere close to using the available cpu resources.
mustISignUp
Could you post Instruments' report somewhere so we can see it?
Yuji
@Yuji sorry, I can't, or else I would spill corporate secrets.
BastiBechtold