18

This is probably a naive question here but I'll ask it anyway.

I'm working with Core Audio (C API) on iOS and am mixing C with Objective-C. My class has the .mm extension and everything is working so far.

I've read in different places about Objective-C being slow (without much detail given - and I am not making any declaration that it is). I understand about not calling Objective-C from a Core Audio render callback, etc. and the reasons why.

On the other hand, I need to call in to the class that handles the Core Audio stuff from my GUI in order to make various adjustments at runtime. There would be some walking of arrays, mostly, shifting data around that is used by Core Audio. Would there be any benefit speed-wise from writing my functions in C and storing my variables in, say, vectors rather than NSMutableArrays?

I've only been working with Objective-C/iOS for a few months so I don't have any perspective on this.

Black Frog
  • 11,595
  • 1
  • 35
  • 66
spring
  • 18,009
  • 15
  • 80
  • 160
  • 8
    If CoreAudio is a C API, then why are you compiling it as a Objective-C++ File? – Richard J. Ross III Mar 12 '12 at 14:17
  • Agreed. Just a plain Objective-C file is all that's needed. – wadesworld Mar 12 '12 at 15:29
  • I am using std:vector instead of NSArray (thought they would be faster)- so I needed .mm in order to get it to compile. Maybe I don't need to use std:vector. – spring Mar 12 '12 at 16:09
  • 3
    possible duplicate of [Is C++ faster than Objective-C?](http://stackoverflow.com/questions/926728/is-c-faster-than-objective-c) – Brad Larson Mar 12 '12 at 17:58
  • 1
    See also [Does C code run faster?](http://stackoverflow.com/questions/9605851/does-c-code-run-faster) – Brad Larson Mar 12 '12 at 18:50
  • To use std::vector, you do need .mm. However, as discussed, use Objective-C's strengths to write the best, cleanest code you can. That means using Obj-C native datatypes wherever possible. – wadesworld Mar 13 '12 at 00:37

7 Answers7

30

Objective-C is slightly slower than straight C function calls because of the lookups involved in its dynamic nature. I'll edit this answer with more detail on how it works later if nobody else adds in the detail.

However, more importantly, you are optimizing prematurely. There's a VERY high chance that the extra overhead of Objective-C will have zero noticeable impact on your application's performance.

Take advantage of Objective-C's strengths to design the best written, most object-oriented application possible. If, and only if, testing shows performance problems, optimize those particular areas of the application.

wadesworld
  • 13,535
  • 14
  • 60
  • 93
  • 7
    I upvoted, but I'll also comment to emphasize how important this is. Early optimization does not make sense. – Almo Mar 12 '12 at 14:27
  • thanks - that sounds like good advice. I just wanted to avoid going down a known "slower road", so I thought I would ask. – spring Mar 12 '12 at 16:04
  • I agree completely, although Core Audio is one of the areas where plain C code can make a difference. Running through 44,100 audio samples (176,400 bytes in 16-bit stereo) every second can bring an older iDevice to its knees with just a few method calls. See http://www.mikeash.com/pyblog/why-coreaudio-is-hard.html – EricS Mar 13 '12 at 03:38
  • You will know when you profile it in Instruments and see `objc_msgSend` at the top... otherwise I wouldn't worry about it. – nielsbot Oct 12 '13 at 03:22
  • If you do find that `objc_msgSend` is consuming a lot of time in an inner loop, for example, you can optimize that away by looking up the implementation function (IMP) for your heavily used methods and then calling those directly. – nielsbot Oct 12 '13 at 03:23
  • finally, std::vector sux – nielsbot Oct 12 '13 at 03:23
  • @nielsbot Indeed, calling through an `IMP` can actually be faster than a “normal” C/C++ function call in some cases (e.g. if the function is in a dynamic library, or if it’s a C++ virtual function). – al45tair Mar 06 '14 at 08:45
7

The main performance hit with Objective-C is in the work required to dispatch a method invocation. Objective-C is dynamically bound, which means that the object receiving the message (selector) decides what to do with it at run time. This is implemented with a hash table. The selector is hashed (at compile time I think) and mapped to the method that gets invoked via a hash table, and it takes time to do the look up.

Having said that, the method lookup – which happens in objc_msgSend() is highly optimised. In fact, it is hand crafted in assembler. I've heard it said that the overhead compared to a C function call is about 20 machine instructions. Normally, this is not a big deal, but if you are running through a 100,000 element NSArray, looking up each element with -objectAtIndex: that becomes quite a bit of overhead.

In almost every case, however, the extra flexibility and functionality is worth the cost. This is why wadersworld's answer contains fine advice.

Bill Bumgarner has written an awesome set of articles on objc_msgSend()

jscs
  • 63,694
  • 13
  • 151
  • 195
JeremyP
  • 84,577
  • 15
  • 123
  • 161
4

While other answers have quantified that the dynamic method dispatch (objc_msgSend), being hand-tuned assembly adds about 20 machine instructions, there's another possible cause of poorer performance in Objective-C as compared to C: Objective-C's has a richer foundation library.

One such performance comparison had a game generating terrain, as follows:

  • The pure C version gave 60 fps
  • The objective-C version gave 39 fps

The reason for the slow down was the the NSMutableArray being used includes all kinds of safety checks, and is able to grow and shrink to the required size, whereas the C array was fixed sized - go ahead and write beyond the bounds if you want, just be ready for bad things to happen.

Fortunately, as other have said, it's very easy to do later performance analysis, and swap in some pure C code, in the places where it will count.

Jasper Blues
  • 28,258
  • 22
  • 102
  • 185
3

Slow is relative.

Objective C messaging is slow relative to accessing lots of small data type elements (every pixel in a large image bitmap or every audio sample in an entire song) inside innermost loops. Objective C is really fast relative to doing anything at the rate of UI or even display refresh events.

For handling Core Audio raw samples, stick with using C. For handling Core Audio events related to UI (stop, start, properties, etc.), encapsulating them in Objective C won't make any measurable speed difference.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
1

Objective-C is not slow, it is literally C with objects.

A class in Objective-C consists of a few different things:

  • A map of selectors to functions (method implementations)
  • A map of names to types (instance variables)
  • A map of names to types & functions (properties)

So, Objective-C will be just about as fast as calling the raw C functions yourself, with a little bit of overhead for looking up a function.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
  • @Goz that overhead is about 8-10 cycles on x86, and around 10-15 on ARM. So, a 'little' is correct. – Richard J. Ross III Mar 02 '14 at 21:01
  • Someone benchmarked a recursive function with C and obj-C. http://goo.gl/hFXN1I. Due to the relatively simple nature of the function call itself more of the overhead you see is obj-c messaging over C function calls ... which is quite heavy ... That said the more work performed inside the call the less significant the overhead ... so YMMV and all that sort of thing. – Goz Mar 02 '14 at 22:06
  • 1
    @Goz obviously, some logic must be used. If that small overhead is bottleneck, the flexibility of ObjC allows you to turn it into C++ or C. It's not a 'one size fits all' deal, and that's the beauty of the language is the ease with which you can use other languages with it. – Richard J. Ross III Mar 02 '14 at 22:19
  • Which I would suggest is worth adding to your answer ;) – Goz Mar 02 '14 at 22:32
  • @Goz I think the other answers sufficiently cover that topic, and I see no real reason to bump this to the front page again, and get even more duplicate answers here. – Richard J. Ross III Mar 02 '14 at 22:45
0

objective c is fast like c because there is no Objective C Compiler and all objective C code is resolved to C using structures and function pointers. Objective C is the way in which we can write object oriented programming in C. All the features of an object oriented programming language(Small Talk in objective C) are made using C. Actually we can define an object in C by using structures (can have instance variables of a class) and related functions manipulating that data. Message passing or calling object function is done by using the function

objc_msgSend(receiver,selector,arg1,arg2....)

That is C, and an Objective C processor gives Objective C. When we are compiling Objective C code it is converted in to pure C and C code is compiled and run. The difference between C and Objective C is speed.

joao
  • 3,517
  • 1
  • 31
  • 43
rahulck
  • 11
  • 1
  • But this call needs to perform a dynamic look-up in a method table and that every time the method is called. C on the other hand does static dispatch. Static dispatch is much faster. Calling a C function is about 3-6 times faster than calling an Obj-C method, so how can they be equally fast? They can only be equally fast if you never call methods in Obj-C but that some defies the purpose of using Obj-C. – Mecki Aug 03 '17 at 15:20
0

It all depends on what you are doing. Using core audio, 99% of your execution time should be spent in library functions anyway. Now if you do something stupid - take a second worth of samples, turn each into an NSNumber, store them into an NSMutableArray, and do a hand written FFT with calls of [[myArray objectAtIndex:i] doubleValue], you get what you deserve. The slowest iPhone can do quite a few method calls per microsecond.

Whether you use a C function or an Objective-C method doesn't make a difference. The only difference is how many Objective-C methods you call. Lots of tiny Objective-C methods called a million times is a lot of overhead. And there is no law that forbids the use of C arrays in Objective-C code.

The rule for speeding up things: Use Instruments. Measure the execution time. Pick where the execution time is high, speed things up, measure again. And most of the time you don't get speedup by replacing good code with better code, but by replacing massively stupid code with reasonably good code.

gnasher729
  • 51,477
  • 5
  • 75
  • 98