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.
Related
There are tons of articles and blog posts over the internet telling that mutable objects are bad and that we shouldn't use them and therefore we shall make all our objects immutable.
I have nothing against this except that the topic has gone so far that some people might be "tricked" into thinking that mutable objects shall never be used at all.
When do we have to resort to use mutable objects? What are the common kinds of problems that are unsolvable without using mutable state?
As to your fear, it's common. Every concept gets taken by some as to mean that nothing else shall ever be done, for any reason.
These are the people who try to make requirements fit their ideology, rather than the other way around (a.k.a. they're not pragmatic).
When to use mutables? Basically when you feel like it, when you think it makes sense.
Prime example is in low memory and high performance situations where creating a new instance that's identical except for one little thing from the old one is too expensive in either memory and/or CPU cycles.
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 need to store large amounts of unsigned chars and/or ints (potentially 100,000,000 and up) in an array. Mathematical operations will frequently be performed on the numbers in this array, so the array will be modified often, and the length of the array can potentially change often as well.
I can use C or Objective-C (or both). Performance wise, would it be better to use a plain C array and realloc it as necessary, or just go for an NSMutableArray? Or does anyone have any better ideas?
Please note that performance is my main concern, I am willing to write extensive reallocation code if necessary.
Also: Memory usage is a consideration, but not a concern (as long as it doesn't end up using multiple gigabytes).
Using an NSMutableArray means you have the overhead of two Objective-C message sends every time you want to get or set the value of an array element. (One message to get the element as an object, and a second to get its value as a primitive int.) A message send is much slower than a direct array access.
You could use a CFMutableArray instead of an NSMutableArray, and specify callbacks that let you store bare numbers instead of objects. But you would still need to use a function call to get or set each array value.
If you need peak performance, just use a plain C array, or a std::vector if you want to use Objective-C++.
Will your array need to grow much and how much ?
Using realloc is not very performant.
That's why I would recommend a linked list as you can find GSList in glib.
The container:
How about C++? Objective-C++ and STL might be a point, STL was made by smart people and it's actually quite efficient in skilled hands. Although, having potentially up to 100,000,000 entries requires some optimization tricks in any cases.
The framework:
You haven't specified the task itself, could it be suitable to use something like CoreData or maybe SQLite? The math can be done with SQL procedure.
The first one is good if you have some, mmm, data samples - pixels, audio chunks or something like that. The second way is definitely preferred in most other cases.
I have read Apple's memory management guide, and think I understand the practices that should be followed to ensure proper memory management in my application.
At present it looks like there are no memory leaks in my code. But as my code grows more complex, I wonder whether there is any particular pattern I should follow to keep track of allocations and deallocations of objects.
Does it make sense to create some kind of global object that is present throughout the execution of the application which contains a count of the number of active objects of a type? Each object could increment the count of their type in their init method, and decrement it in dealloc. The global object could verify at appropriate times if the count of a particular type is zero of not.
EDIT: I am aware of how to use the leaks too, as well as how to analyze the project using Xcode. The reason for this post is to keep track of cases which may not be detected through leaks or analyze easily.
EDIT: Also, it seems to make sense to have something like this so that leaks can be detected in builds early by running unit tests that check the global object. I guess that as an inexperienced objective-c programmer I would benefit from the views of others on this.
Each object could increment the count of their type in their init
method, and decrement it in dealloc.
To do that right, you'll have to do one of the following: 1) override behavior at some common point, such as NSObject's -init or , or 2) add the appropriate code to the designated initializer of every single class. Neither seems simple.
The global object could verify at appropriate times if the count of a
particular type is zero of not.
Sounds good, but can you elaborate a bit on "appropriate times"? How would you know at any given point in the life of your program which classes should have zero instances? You'd have a pretty good idea that there should be no objects at the end of the program, but Instruments could tell you the same thing in that case.
Objective-C has taken several steps to make memory management much simpler. Use properties and synthesized accessors where you can, as they essentially manage your objects for you. A more recent improvement is ARC, which goes even further toward automating most memory management tasks. You basically let the compiler figure out where to put the memory management calls -- it's like garbage collection without the garbage collector. Learn to use those tools well before you try to invent new ones.
Don't go that route... it's a pain in single inheritance. Most importantly, there are excellent tools at your disposal which you should master before thinking you must create some global counter. The global counter exists in a few tools already -- Learn them!
The way you combat it is to learn how to balance and manage everything correctly when it's written. It's really very simple in hindsight.
ARC is another option -- really that just postpones your understanding.
The first "design pattern" I recommend it to use release instead of autorelease where possible (although generally more useful for over-releases).
Next, run the leaks instrument/util regularly and fix all leaks/zombies immediately.
Third, learn the existing tools as you go! These tools can do really crazy stuff, like record the backtrace of every allocation and every reference count. You can pause your program's execution and view what allocations exist, alloc counts, backtraces, and all sorts of other stats.
I want to perform the same action over several objects stored in a NSSet.
My first attempt was using a fast enumeration:
for (id item in mySetOfObjects)
[item action];
which works pretty fine. Then I thought of:
[mySetOfObjects makeObjectsPerformSelector:#selector(action)];
And now, I don't know what is the best choice. As far as I understand, the two solutions are equivalent. But are there arguments for preferring one solution over the other?
I would argue for using makeObjectsPerformSelector, since it allows the NSSet object to take care of its own indexing, looping and message dispatching. The people who wrote the NSSet code are most likely to know the best way to implement that particular loop.
At worst, they would simply implement the exact same loop, and all you gain is slightly cleaner code (no need for the enclosing loop). At best, they made some internal optimizations and the code will actually run faster.
The topic is briefly mentioned in Apple's Code Speed Performance document, in the section titled "Unrolling Loops".
If you're concerned about performance, the best thing to do is set up a quick program which performs some selector on the objects in a set. Have it run several million times, and time the difference between the two different cases.
I too was presented with this question. I find in the Apple docs "Collections Programming Topics" under "Sets: Unordered Collections of Objects" the following:
The NSSet method objectEnumerator lets
you traverse elements of the set one
by one. And
themakeObjectsPerformSelector: and
makeObjectsPerformSelector:withObject:
methods provide for sending messages
to individual objects in the set. In
most cases, fast enumeration should be
used because it is faster and more
flexible than using an NSEnumerator or
the makeObjectsPerformSelector:
method. For more on enumeration, see
“Enumeration: Traversing a
Collection’s Elements.”
This leads me to believe that Fast Enumeration is still the most efficient means for this application.
I would not use makeObjectsPerformSelector for the simple reason that it is the kind of call that you don't see all that often. Here is why for example - I need to add debugging code as the array is enumerated, and you really can't do that with makeObjectsPerformSelector unless you change how the code works in Release mode which is a real no no.
for (id item in mySetOfObjects)
{
#if MY_DEBUG_BUILD
if ([item isAllMessedUp])
NSLog(#"we found that wily bug that has been haunting us");
#endif
[item action];
}
--Tom
makeObjectsPerformSelector: might be slightly faster, but I doubt there's going to be any practical difference 99% of the time. It is a bit more concise and readable though, I would use it for that reason.
If pure speed is the only issue (i.e. you're creating some rendering engine where every tiny CPU cycle counts), the fastest possible way to iterate through any of the NSCollection objects (as of iOS 5.0 ~ 6.0) is the various "enumerateObjectsUsingBlock" methods. I have no idea why this is, but I tested it and this seems to be the case...
I wrote small test creating collections of hundreds of thousands of objects that each have a method which sums a simple array of ints. Each of those collections were forced to perform the various types of iteration (for loop, fast enumeration, makeObjectsPerformSelector, and enumerateObjectsUsingBlock) millions of times, and in almost every case the "enumerateObjectsUsingBlock" methods won handily over the course of the tests.
The only time when this wasn't true was when memory began to fill up (when I began to run it with millions of objects), after which it began to lose to "makeObjectsPerformSelector".
I'm sorry I didn't take a snapshot of the code, but it's a very simple test to run, I highly recommend giving it a try and see for yourself. :)