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.
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?
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.
I am a new cocoa developer coming from a C#/Java background. I had been introduced to memory management patterns which objective-c language uses and I just find them very helpful for code-conscious development.
Why does Apple now want us to use ARC (Automatic Reference Counting) instead of MRR (Manual Retain-Release) and what advantages other than time saving does ARC offer?
I see such a transition negatively affecting good-citizen habits that developers gain from the obj-c ecosystem.
Nick
It's unfortunate that making it easier for competent developers to be correct has a side effect of making it easier for new developers to not learn, but it seems like it's probably worth it.
ARC is less forgiving than a tracing collector like C# or Java use though. If you don't have a clear object ownership model you will almost certainly create cycles and leak tons of memory. My hope would be that this is made obvious enough (via Instruments? That still requires seeking it out... not sure what could be done here) that new developers will quickly learn to keep their object graph clear and acyclic.
ARC allows me to concentrate on writing useful code instead of boilerplate dealloc methods.
Most people I know have used autorelease behind every alloc anyway, because it saved you a release later and you couldn't forget to actually put it. So the object was around until the autorelease pool was drained, and with ARC the object gets deallocated when it isn't needed anymore. I think in those cases the ARC-compiled program will even use less memory.
And, shame on me, it helps me to make my apps crashing less often too.
That premature release that happens every 10.000 launches. The one that I could never track down completely, hopefully with ARC this is a thing of the past.
I see such a transition negatively affecting good-citizen habits that developers gain from the obj-c ecosystem.
probably in the same way an embedded developer who started with assembler thinks people that start with C and have never used assembler get into bad habits.
In my opinion the MRR vs ARC discussion is similar.
ARC and C both allow to write more maintainable code in a shorter time.
And both of them can lead to a larger memory and cpu footprint.
If I remember correctly Apple announced that they did add a little speed up to retain and release to compensate that impact on cpu usage. And because of that there is no real reason that MMR is still around.
I, for one, welcome our new ARC overlords.
i've actually rather enjoyed moving to ARC - it's one less thing to think about. on top of that, i think newcomers would often be tripped up by the significance of naming conventions (+alloc, -copy etc vs [NSString stringWith....]). the only tricky bit is when you start dealing with CoreFoundation etc (the C APIs) where you still have to keep in mind just who is owning what.
I'm getting my feet wet in Objective-C and Cocoa and I noticed that all objects are allocated out of the heap.
Is there any reason why this is the standard in Objective-C? I'm especially keen because Objective-C is considered a strict super-set of C with OO features.
I think this owes to the Smalltalk heritage.
Also, you could say that stack-allocated objects are a peculiarity of C++. Very few other languages do that, and then mostly as a low-level optimization for the compiler. In C++ it's reasonable, since one of the stated goals was to be exactly as performant as plain C.
Why do you feel this is in conflict with the fact that Objective-C is a super-set of C? After all, plain C can't either allocate objects on the stack... nor anywhere. structs, OTOH, are allowed on the stack, both on C and Objective-C
I'm not exactly answering your question, but since you are understanding Obj-C's runtime, here it goes. You can allocate objects more efficiently using NSZones. You won't have them on the stack, but at least you can avoid some fragmentation and performance issues:
link text
Hopefully, this question isn't a dumb as I fear it sounds, but it may still be pretty dumb.
I'm new to Objective-C, and Cocoa. In fact, I'm completely new to C in general. I'm trying to implement an iPhone game using Cocos2d-iPhone. It's a game I've made before in Flash, so I thought it would be a nice way to lean Objective C, cocoa and cocos2d.
One thing I am having a big problem with is understanding why all the Chipmunk code looks different to all the normal Objective-C stuff. For example, there's stuff like
chipmunkBody->position.x
which I thought would have been
chipmunkBody.position.x or maybe [[chipmunkBody position] x] (bad example maybe).
One way this keeps on biting me in the ass is with cpVect. cpVect is pretty important, but I can't for the life of me figure out how to pass it around. CGPoint, no problem, I can make pointers, pass them around in methods and what not, but the second I use cpVect instead, it's "welcome to Errorville, population you".
So that's the question, what is Chipmunk, so I can start finding out more about working with it.
thanks
-t
I haven't used Chipmunk, but it's probably written in C/C++. That's the reason.
EDIT: Yup, it's written in C.
chipmunkBody is a pointer to a struct, and the arrow operator (->) is how you access the members of a struct through a pointer to the struct in C.
In case you're looking for an easy way to use Chipmunk thru way of Objective-C, Theres a nice little post about an Objective-C class called SpaceManager here: http://www.mobile-bros.com/?p=126