1

When I use NSMutableArray or NSMutableDictionary, if I know the number of elements I want to put in or the max number of elements, I usually create them with arrayWithCapacity or dictionaryWithCapacity, but I wonder does it really help to specify an (initial) capacity for the array/dictionary?

I don't know how it is implemented internally, but I believe it is possible that when the number of elements in a collection hits the capacity or even approaches the capacity, the collection may extend its capacity, so if I created a mutable array with capacity 32, as long as I put the 32nd object in it, it will expand itself to another capacity? Or even if I put the 30st object in it, its capacity will be expanded as it thinks there will be more objects?

So if these methods really help, should I use something like:

 *withCapacity:maxNumberOfElements * 1.5

instead of

*withCapacity:maxNumberOfElements

so it will have more than enough capacity for my objects and won't expand when I put in all the objects?

hzxu
  • 5,753
  • 11
  • 60
  • 95
  • I have been programming obj-c for years, and in practice this never comes up. I wouldn't worry about when a collection will grow. The only time I use `arrayWithCapacity:` is when I already know how many items I am going to insert. Otherwise I just use `[NSArray array]` et al. – nielsbot Aug 20 '12 at 00:56

3 Answers3

0

Its useful from a performance standpoint. When the capacity gets expanded often times a new array is allocated in memory(usually at 2x the capacity of the current one) and the old array is copied to the new array. This can start to get expensive as the # of elements increases, so if you have large arrays where the capacity is(roughly) known in advance, its advisable to use initWithCapacity. On the other hand, if you allocate something much bigger than needed, you are wasting space, so standard "use with caution" warning applies.

user439407
  • 1,666
  • 2
  • 19
  • 40
0

Realistically speaking, unless you're creating a lot of arrays/dictionaries (compared to the frequency of, say, presenting UI pages), there's not going to be a measurable improvement in performance from using ...WithCapacity. And even then there's really no point in worrying about it unless you have arrays/dictionaries with at least several hundred entries.

In terms of what size to guestimate, probably a little (5-10%) over the final size is ideal, but it depends in part on whether you're apt to be storage-constrained.

If you know exactly how many entries, though, specify that exact amount (if you specify anything).

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
0

This is useful when you are planning to populate a collection with a large number of elements, or when you know the exact number of elements that you are going to load. Resizing a collection takes CPU cycles, so resizing unnecessarily ultimately translates into reducing the time your device can operate on a battery.

Consider this example: let's say you are about to load 3000 elements into an array. If you allocate the default array with space for, say, 16 items, the array will need to resize eight times before arriving at the size necessary to hold 3000 elements. The elements copied in the initial positions will need to be copied each time the array is resized, resulting in 3000+ additional copy operations. When you know the exact number of elements, you can prevent the copying from happening.

In addition, your array will not waste memory for elements that you are not going to add: if you add 3000 elements one by one, the array may grow to 4000 internally in anticipation of more elements; the last 1000 elements will be wasted.

To summarize, you should initialize your collections with capacity when you know the exact target size for sure. This situation comes up often when you deserialize data from a file or a network connection. In situations when you do not know the size, it is better not to make guesses, and let the default initialization run its course.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Note that you should *always* profile before trying to optimize like this. Identify areas of poorly-performing code before wasting brain cycles on stuff that users might never notice. – Jonathan Grynspan Aug 20 '12 at 02:37
  • @JonathanGrynspan I agree, one should not try to guess the right number. The only case when it's a clear-cut decision is when you know the exact number with 100% certainty; in all other cases, one should profile. – Sergey Kalinichenko Aug 20 '12 at 02:46