Does anyone have advice on how to best initialize an NSMutableArray when it comes to dictating the capacity? The documentation mentions that "...even though you specify a size when you create an array, the specified size is regarded as a “hint”; the actual size of the array is still 0." So...
1) If I init with a greater capacity than I typically use, do I not have to worry about wasted memory?
2) If I init with a capacity typically lower than what I use, do I have to worry about heavier processing time allocating more memory to hold the extra elements?
Just how impacting is this initialized capacity to the performance/memory usage of this data type?
Matt Gallagher has written a pretty informative article on Cocoa's collection classes, along with a couple of benchmarks (with & without initWithCapacity:
, as well as cross class comparisons)
http://cocoawithlove.com/2008/08/nsarray-or-nsset-nsdictionary-or.html
His test (source available) for an NSMutableArray of length 1,000,000 took 0.582256sec without capacity and just 0.572139sec with capacity.
Test | Time [NSMutableArray array] | 0.582256 seconds [NSMutableArray arrayWithCapacity:1000000] | 0.572139 seconds Iterating contents | 0.004713 seconds
I'd say that in 99% of the use cases [NSMutableArray array]
is just fine. If you do know the actual size of the resulting array, however, it won't hurt to use [NSMutableArray arrayWithCapacity:]
either.
And then there is this article by Peter Ammon (who is a developer on Apple’s AppKit/Foundation team) featuring several insightful benchmarks:
http://ridiculousfish.com/blog/archives/2005/12/23/array/
Edit (March 12th 2012):
More insight on array initialization performance from http://darkdust.net/writings/objective-c/nsarray-enumeration-performance
[…] I [=>DarkDust] also wanted to know whether the performance is any different depending on how the array was created. I tested two different methods:
- Create a C array which references the object instances and create the array using
initWithObjects:count:
.- Create a
NSMutableArray
and subsequently add objects usingaddObject:
.[…] there is a difference when allocating: the
initWithObjects:count:
method is faster. With a very large number of objects, this difference can become significant.
Edit (March 6th 2014):
Further more insight on array initialization performance from http://ciechanowski.me/blog/2014/03/05/exposing-nsmutablearray/:
Let’s allocate new arrays with initial capacity set to consecutive powers of two:
for (int i = 0; i < 16; i++) { NSLog(@"%@", [[[NSMutableArray alloc] initWithCapacity:1 << i] explored_description]); }
Surprise surprise:
size: 2 // requested capacity: 1 size: 2 // requested capacity: 2 size: 4 // requested capacity: 4 size: 8 // requested capacity: 8 size: 16 // requested capacity: 16 size: 16 // requested capacity: 32 size: 16 // requested capacity: 64 size: 16 // requested capacity: 128 ... // 'size: 16' all the way down