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.
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.
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()
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.
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.
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.
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.
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.
Related
I'm working on a performance-intensive Swift app, with most of the fast code residing inside a framework. One of my expensive functions involves iterating over a two-million element array of structs. Unfortunately, the Obj-C bridge makes Swift Array performance about an order of magnitude slower than it should be. About 90% of my cycles are wasted on _ArrayBuffer._checkInoutAndNativeTypeCheckedBounds and bridging-related retains and releases. If I drop the framework and simply include those same files as part of my target, performance improves 10x. However, I'd prefer to keep the framework around if possible.
Is there any way to tell my frameworks not to do any Obj-C bridging, i.e. just use straight Swift?
I am trying to decide between Swift and Objective-C for my app. Currently I am testing performance for operations that will happen a lot in the app.
I have written a testapp that downloads a json file and puts it in a NSDictionary like this:
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println(jsonResult)
And when I test it, Objective-C seems to be faster everytime. But there's no difference in using the optmization (-Ounchecked) and no optmization(-Onone). I know the println is the biggest slowdown in both Objective-C and Swift.
Does the lack of optimization have anything to do with the fact that it's barely possible to optimize that line?
As you say, there's nothing in the above program to optimize. You can check for yourself by looking at the assembly output, but I would expect them to be almost identical.
In general, things heavily involving Cocoa are going to be as fast or faster in ObjC today than Swift. The ObjC compiler has decades of work behind it, and Cocoa has decades of ObjC-specific optimization. There is nothing Swift can do to make a call to an existing Cocoa method faster. NSJSONSerialization is the same class in ObjC and Swift.
It is possible for Swift to be faster than pure ObjC in things that you would traditionally use C or C++ for anyway. It is possible for an [Int] to be faster than an NSArray of NSNumber for certain operations (but see this question before you assume that NSArray is slow), just like it's possible for vector<int> or int[] to be faster for those same operations (and for roughly the same reasons). But that's a poor reason to choose Swift. If numerical calculations are your major problem, and performance is at a premium, then C and C++ have decades of optimization behind them. Swift might beat them here and there, but C and C++ are known quantities.
But micro-benchmarks like these are useless in working out performance questions. They're not going to tell you much about your app's total performance. That comes from profiling real code, and then optimizing your bottleneck. And in some cases that might mean moving some piece of Swift code into ObjC (or C or C++), just like we've long converted pieces of ObjC to C or C++ when we needed to improve certain kinds of performance.
Swift is neither easier to read nor understand than ObjC. It is in certain cases easier to write (though often it is much harder). It is much easier to write correct code with fewer bugs because of better typing, and that's why I think it's going to be a great language. But not because it's "easier."
Swift appears easier because its syntax is slightly closer to Java and JavaScript and many people who are evaluating it have a Java and JavaScript background, but Swift's dramatically more complex features and rough edges when working with Cocoa make understanding much more difficult. Why do you need as NSDictionary in the above code? How is a new programmer supposed to know that? The equivalent ObjC has no such weirdness. When you start doing more work, you'll discover many very confusing compiler errors any time AnyObject shows up (and it shows up all the time with Cocoa). Don't be fooled by the parentheses versus square brackets. ObjC is a much simpler language with years of tutorials, StackOverflow Q&A, books, and training available. (Also the ObjC compiler almost never crashes.)
IMO, if you are uncertain, then use ObjC. ObjC is what Cocoa is designed for. ObjC has a well-established compiler. ObjC is easier to learn (it's harder to just dive into and start hacking at things, but it's easier to actually learn).
As Swift settles down (and it's quickly settling down), you can convert parts of your app to Swift. Swift was designed to allow you to mix it this way, and it's getting easier to do that in practice (particularly with the new ObjC annotations). But if you have any serious deadlines ahead of you, I strongly recommend ObjC.
On the other hand, if you don't have a serious deadline, and you like Swift better, go for it. I think it's going to be a great language some day.
I have an Objective C++ class, instances of which are required to store an arbitrary set of C++ objects and associate each with a corresponding Objective C object. Looking up the Objective C objects when given the C++ object is killing my performance, so I'm looking for a better solution.
I'm currently storing the pairs in an NSMutableDictionary after creating the keys using [NSValue valueWithPointer:]. The lookup time, in which +valueWithPointer: is about twice as expensive as -objectForKey:, is simply too slow.
The C++ objects are in a third-party framework, and do not provide any unique identifier.
The sets of C++ objects are always smaller than a dozen elements.
What is a faster approach to performing these lookups?
I see three approaches that seem worth trying:
Use NSMapTable
Use objc_setAssociatedObject
Use std::unordered_map or std::map
objc_setAssociatedObject uses std::unordered_map behind the scenes.
I had a similar issue recently with [NSValue valueWithNonRetainedObject:] being too slow.
The solution I went with was to drop down a level and use CoreFoundation's CFMutableDictionary. I would suggest you take a look at it: CFMutableDictionary Reference. It takes regular C pointers in CFDictionaryAddValue(), CFDictionaryRemoveValue, so it's the best thing to use to interface Obj-C and C++ (C is their common denominator).
The reason I'd rather do that than use an std::unordered_map is because I tend to want to minimise C++ in these kind of things. Obj-C++ is a bit of a hack and it's best to just reduce it to glue code between real Obj-C and existing C++ code.
I'm attempting to piece together and run a list of tasks put together by a user. These task lists can be hundreds or thousand of items long.
From what I know, the easiest and most obvious way would be to build an array and then iterate through them:
NSArray *arrayOfTasks = .... init and fill with thousands of tasks
for (id *eachTask in arrayOfTasks)
{
if ( eachTask && [eachTask respondsToSelector:#selector(execute)] ) [eachTask execute];
}
For a desktop, this may be no problem, but for an iphone or ipad, this may be a problem. Is this a good way to go about it, or is there a faster way to accomplish the same thing?
The reason why I'm asking about how much overhead a msg_send occurs is that I could also do a straight C implementation as well. For example, I could put together a linked list and use a block to handle the next task. Will I gain anything from that or is it really more trouble than its worth?
I assume you're talking about objc_msgSend, in which case, Bill Bumgarner has an excellent
4 Part Series that is worth a read.
In general though, I would recommend simply using Obj-C. This is what all apps for the iDevices use, including Apple, and hundreds of items is not going to kill the device.
What rynmrtn said...
Unless your -execute methods were exceedingly simplistic -- incrementing / testing a small handful of scalar values -- then it is unlikely that objc_msgSend() will even show up as a % of your program's CPU time.
Measure first, optimize after.
Your code does raise a question; why are you putting things into the arrayOfTasks that might not be able to execute. Assuming everything in your arrayOfTasks is a subclass of your making, you could add an execute method and not do the responds test. If you have a hierarchy of collection classes, you could use categories to add the methods -- just put a prefix on 'em to be safe (i.e. pxl_execute or something).
Here is a nice benchmark comparison of common operations, including objc_msgSend. In general, you shouldn't worry about objc_msgSend performance, even on the iPhone. Message sending will always be slower than a straight C function call, but on a modern processor (remember, the iPhone processor is still about 500 mhz), the difference is trivial most of the time. If profiling shows that a lot of time is being used in objc_msgSend, then it might be worth using straight C functions instead of Objective-C methods.
For clarity, you can use -[NSArray makeObjectsPerformSelector:] or (on Mac) enumerateObjectsUsingBlock: instead of iterating through the objects, but I don't think it should make much performance difference.
I'm curious to know about the cost of message dispatch in Objective-C in various situations. Particularly I want to guide my choice of program design so I'm not tempted to prematurely optimize by avoiding message dispatches when they would make for a better design.
A case in my current project is that I have a class with instance variables: offsetX and offsetY. I often want the absolute offset and at the moment I have this line of code all over the place:-
int absOffset = ((offsetX < 0.0) ? -offsetX : offsetX) +
((offsetY < 0.0) ? -offsetY : offsetY);
Now if this was C++ I would create an inline function that returned the value for absOffset. Even in Java/C# I could define such a function as final/sealed and be pretty sure it would be inlined.
The objective-C would be:-
-(int)absOffset {
return ((offsetX < 0.0) ? -offsetX : offsetX) +
((offsetY < 0.0) ? -offsetY : offsetY);
}
and I would call it like so:-
int ao = [self absOffset];
Now, is the compiler able to inline that? I assume it is able at least fix it to a direct function call and avoid the dynamic message dispatch that (I assume) objective-c must use because of it's type system.
Also, in general, how much does message dispatch cost in objective-C? Does it differ when calling through an 'id' versus a pointer to a concrete class?
Objective C messages are very fast. The speed is comparable to C++ virtual method calls, although not quite as fast. Avoiding message passing is definitely premature optimization. You might not want to do a lot of it in an inner loop, but the algorithms you choose and other factors will have a much bigger factor on how fast your code is. If it is too slow, use a profiler and go from there.
First, I'd use the C function, fabs() for this. For other things writing simple, inline, C functions for little helper cases can work well. Using methods for convenience rather than discreet behaviour can be a sign of bad design. Performance doesn't even come into it yet.
Next, the compiler cannot optimise a method call away. It's a dynamic language, the call is not resolved until runtime. Various Objective-C techniques could defeat any attempt of the compiler to do so.
There is no difference at runtime between calling a method on an "id" vs a typed pointer - they go through exactly the same mechanism.
Finally, if you're thinking about the performance characteristics before measuring you are already prematurely optimising. That's not to say that is never appropriate, as some might have you believe, but it does usually hold true. In this case, I think, if you put the design first you'll probably end up with a decent enough performance profile anyway. Measure and optimise later, as necessary.