views:

293

answers:

3

I wonder if this affects performance or memory consumption a lot. I need an NSMutableArray, and at the beginning I can only guess how many objects will be added. About 3 to 5 maybe. So I create it like this:

NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:3];

What happens here exactly, when creating it with a capacity of 3 rather than 50 for example? Would it be a bad idea to create it with capacity of 1, when knowing that there will be at least 20 elements? Or does that not matter enough to take some headaches on it? I have like 10 of these arrays in my app and they all have to load at start.

+5  A: 

It's not a big deal unless you're talking about extreme repetition or enormous arrays. It's not worth trying to optimize unless it becomes a real bottleneck.

EDIT: I'd like to add a quote from Donald Knuth:

Premature optimization is the root of all evil.

Thom Smith
what that does premature thing mean? My english is not so great ;-) please explain. thanks!
HelloMoon
It means: don't optimize your code's performance until and unless you a) really need it to run faster and b) identify the slow parts. Otherwise, you simply make your code more complicated, adding complexity and spending time for no benefit.
Thom Smith
makes sense :-)
HelloMoon
+3  A: 

There's the theoretical answer and the practical answer. In theory, setting a larger capacity may change the allocation and storage strategy for the array (although called "NSArray" internally the structure is a bit more complex than that).

From a practical standpoint, the array will reallocate as needed and with the numbers you're talking about I doubt there would be any difference whatsoever. I might do an arrayWithCapacity if I knew I'd be putting thousands upon thousands of items in. 3 vs. 50 is essentially meaningless.

The best use for the "withCapacity" from my perspective is just providing an obvious hook to hang your assumptions on, so you could (for example) have in-code documentation of something that you might later want to assert on. but it's by no means required.

From a practical perspective, the best use of your time is to not even think about the issue.

peterb
+3  A: 

initWithCapacity will cause NSMutableArray to preallocate space for that number of elements.

Pushing more data into your NSMutableArray beyond that capacity will cause NSMutableArray to reallocate its underlying memory. This reallocation will also necessitate the entire array be copied from the old (smaller) allocation to the new (larger) one. So there is a performance penalty for making this number too small, but not much of one.

Specifying a capacity greater than what you'll actually use wastes memory, as there will be memory allocated for items that'll never be used.

My recommendation would be that if you know the size of your array typically won't exceed N items, call initWithCapacity:N. The performance penalty of the occasional NSMutableArray bigger than N is acceptable, and it's a penalty you won't have to pay for those arrays that don't go over that limit.

fbrereto
great details! the other answers were great as well. found it never so hard to chose one as accepted. all voted up. thanks all!
HelloMoon
With all due respect, I think this answer is incorrect. Although the capacity is used for hinting in certain cases, it is not the case that creating a mutable array with a capacity of a gigabyte will immediately allocate a gigabyte of memory. If you don't believe me, try it yourself. NSMutableArray *bigArray = [[NSMutableArray alloc] initWithCapacity:1024*1024*1024]; if (!bigArray) { NSLog(@"Array wasn't created!"); } else { NSLog(@"Yep, it was created."); }If you actually FILL this array, you'll see memory usage increase. Not before.
peterb
The documentation for initWithCapacity states that it returns "an array initialized with enough memory to hold numItems objects." There would seem to be some discrepancy between what peterb has observed and what the documentation claims.
fbrereto
This is trivial to test and to measure. Give it a shot, and let us know what you find. I stand by my claim.
peterb
I didn't mean to imply I disagreed with you or thought your experiment was somehow invalid. It's not uncommon in software for the documentation to differ with the implementation, and where they do it's what the code does that really matters.
fbrereto
Sure, I wasn't trying to be prickly!
peterb
In my experience, the documentation does differ often from the reality. Take a look at the event handling things, especially UIControl ;-) there are so many things going on under the hood that they don't even mention, but which would be great to know in order to not get creazy when trying to acomplish things. I think this array thing here is one of those.
HelloMoon