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
Related
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 read this question in stackoverflow.
The excerpt answer provided by bbum is below:
The problem isn't the assignment, it is much more likely that you
declared your instance variable to be BOOL *initialBroadcast;.
There is no reason to declare the instance variable to be a pointer
(at least not unless you really do need a C array of BOOLs).. Remove
the * from the declaration.
1.Is there anything wrong in using a pointer variable even when I do not have to maintain an array of BOOLs?
2.I think even if avoiding them a good practice, it is not specific to objective-C and applies to all programming languages which has pointers.
Please answer my questions.
1.Is there anything wrong in using a pointer variable even when I do not have to maintain an array of BOOLs?
It's not illegal to do so, but it is bad practice. Using a pointer variable requires that you manage that memory (allocate and free it), and there are whole classes of bugs that can occur as a result. If you forget to allocate the memory, or accidentally modify the pointer, your program could crash, or you could overwrite some other part of memory. If you forget to free the memory, you have a memory leak. None of these things can ever happen if you're just using a plain BOOL. In addition, you get no benefit from using a pointer here; you do a bunch of extra work, and get nothing in return.
2.I think even if avoiding them a good practice, it is not specific to objective-C and applies to all programming languages which has
pointers.
I don't know about "all programming languages which [have] pointers", but I would certainly say in any C-based language (C, C++, Objective-C), it's bad practice to use pointers to intrinsic types when a plain variable of that type will do. If you can avoid doing memory management, do so.
On a side note, it is good practice to listen to everything bbum says. Seriously.
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 know there are a lot of questions on pointers out there, particularly now for Objective-C. But I'm looking for some higher level answers to help me understand the paradigms in Objective-C.
I've heard some people say that using pointers in Objective-C is a matter or experience, i.e. some classes demand that you use pointers, others don't. Is this true? And is that the extent of using pointers in Objective-C.
Basically, apart from when you want to explicitly pass reference variable to methods, what are the rules for pointers in Objective-C?
You use a pointer always when referring to something on the heap and sometimes, but usually not when referring to something on the stack.
Since Objective-C objects are always allocated on the heap (with the exception of Blocks, but that is orthogonal to this discussion), you always use pointers to Objective-C objects. Both the id and Class types are really pointers.
Where you don't use pointers are for certain primitive types and simple structures. NSPoint, NSRange, int, NSUInteger, etc... are all typically accessed via the stack and typically you do not use pointers.
As for Why the * in Objective-C?, you might find this question of interest.
I've been reading up on RAII and single vs. two-phase construction/initialization. For whatever reason, I was in the two-phase camp up until recently, because at some point I must have heard that it's bad to do error-prone operations in your constructor. However, I think I'm now convinced that single-phase is preferable, based on questions I've read on SO and other articles.
My question is: Why does Objective C use the two-phase approach (alloc/init) almost exclusively for non-convenience constructors? Is there any specific reason in the language, or was it just a design decision by the designers?
I have the enviable situation of working for the guy who wrote +alloc back in 1991, and I happened to ask him a very similar question a few months ago. The addition of +alloc was in order to provide +allocWithZone:, which was in order to add memory pools in NeXTSTEP 2.0 where memory was very tight (4M). This allowed the caller to control where objects were allocated in memory. It was a replacement for +new and its kin, which was (and continues to be, though no one uses it) a 1-phase constructor, based on Smalltalk's new. When Cocoa came over to Apple, the use of +alloc was already entrenched, and there was no going back to +new, even though actually picking your NSZone is seldom of significant value.
So it isn't a big 1-phase/2-phase philosophical question. In practice, Cocoa has a single phase construction, because you always do (and always should) call these back-to-back in a single call without a test on the +alloc. You can think of it as a elaborate way of typing "new".
My experience is with c++, but one downside of c++'s one phase initialization is handling of inheritance/virtual functions. In c++, you can't call virtual functions during construction or destruction (well, you can, it just won't do what you expect). A two phase init could solve this (partially. From what I understand, it would get routed to the right class, but the init might not have finished yet. You could still do things with that) (I'm still in favor of the one phase)