Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specifics of Objective-C runtime performance penalties

I've been experimenting with using Objective-C (specifically the GNU runtime, I'm not using GNUStep or anything like that) to extend C with objects. So far its going well - it works well and I really like the syntax, however from what I've been reading there is a performance penalty to using Objective-C objects.

I'm not normally one to optimise prematurely but I'm developing a game and so performance will eventually end up being fairly critical - I'd like to know what I'm getting myself into! Several people have suggested that I will be fine using Objective-C in a game as long as my innermost loops are written in standard C, however the question is finding the point where I should make that switch.

So my question is twofold:

  • What exactly will incur a performance penalty? (so I know what I should avoid)
  • Roughly how significant is this performance penalty? (so I can guestimate in advance which bits of my game will need to be written in C anyway)

My guess is that calling methods on an Objective-C object will incurr a penalty, but I wasn't sure what else would - does de-referencing an Objective-C object incurr a similar penalty?

int a = myobj->a;

How about using a try-catch-finally - will this incur a performance penalty in situations where there is no exception thrown?

I realise that to a certain extent I could figure most of this out myself using benchmarks, but I'm relatively new to this and I was hoping for a deeper understanting of how Objective-C works and the nature of any performance penalties.

I'm not interested in C++ for the moment, I'm just experimenting with Objective-C.

like image 550
Justin Avatar asked Feb 25 '23 11:02

Justin


1 Answers

So my question is twofold:

What exactly will incur a performance penalty? (so I know what I should avoid)

Roughly how significant is this performance penalty? (so I can guestimate in advance which bits of my game will need to be written in C anyway)

(my basis from apple's implementations:)

in most cases, the biggest penalty is that every instance method (messaging) is a dynamic call

the cost of this call/message is approximately 4x as costly as a c++ virtual call.

these calls may not be optimized out (unless somebody makes a good implementation to JIT/HotSpot), and the methods, unlike c or c++, may not be inlined.

but there's more than messaging:

your objects will be ref-counted allocations. this means: lots of locking and many individual, small allocations, plus atomics for the ref counting.

objc_msgSend and variants (the meat of the runtime messaging implementation) can take, like 10% of the execution time alone (extreme real world cases).

it can add to the binary size as well.

idiomatic uses push it further from the speed of c++ or c in many areas. (e.g. consider how numbers are passed/handled).

how much it costs you depends on the size of your methods. good ood means your methods will typically be short. you'll either end up with a lot of messages and noticable weight (if it is to be high performance), or compromising your designs.

there are a few other gotchas, like in realtime apps.

int a = myobj->a;

no diff compared to c

...exceptions...

(iirc) apple's previous exception model used to use costly setup, now they are along the lines of c++'s zero cost exceptions (optimized that exceptions will not be regularly thrown, and marginal on entry/setup, but expensive to throw/catch).

if performance is really important, i'd avoid it and just go with c++. it has plenty of features and speed. you'd have a little work to do to get some of the conveniences of objc -- most of that lies in the libraries available, not the language.

like image 147
justin Avatar answered Feb 27 '23 00:02

justin