Нюансы NSMutableArray initWithCapacity

есть ли у кого-нибудь советы о том, как лучше всего инициализировать NSMutableArray, когда дело доходит до диктовки емкости? В документации упоминается, что "...несмотря на то, что вы указываете размер при создании массива, указанный размер рассматривается как "подсказка"; фактический размер массива по-прежнему равен 0." Так...

1) Если я init с большей емкостью, чем я обычно использую, мне не нужно беспокоиться о потерянной памяти?

2) Если я init с емкостью, как правило, ниже, чем что я использую, мне нужно беспокоиться о более тяжелом времени обработки, выделяя больше памяти для хранения дополнительных элементов?

насколько влияет эта инициализированная емкость на производительность / использование памяти этого типа данных?

2 ответов


если какое-либо пространство тратится впустую, давая слишком большую емкость, на самом деле это деталь реализации, которую Apple намеренно не раскрывает, я думаю. NSMutableArray-это кластер классов, который означает, что вы фактически не получаете экземпляр NSMutableArray, а какой-то другой специализированный класс, следующий за тем же интерфейсом. И Apple не говорит вам, какой класс возвращается в каком случае и как он себя ведет. Поэтому здесь трудно давать реальные советы.

Если вы действительно знаете, что в среднем вам понадобится емкость X, просто использовать его. В противном случае, если у вас нет проблем с производительностью, я бы вообще не заботился о емкости и просто использовал [NSMutableArray array]...


Мэтт Галлагер написал довольно информативную статью о классах коллекции Cocoa, а также несколько тестов (с & без initWithCapacity:, а также сравнения кросс-классов)

http://cocoawithlove.com/2008/08/nsarray-or-nsset-nsdictionary-or.html

его тест (источник доступен) для NSMutableArray длина 1,000,0000.582256 сек без возможности и просто 0.572139 сек с емкостью.

Test                                       | Time
[NSMutableArray array]                     | 0.582256 seconds
[NSMutableArray arrayWithCapacity:1000000] | 0.572139 seconds
Iterating contents                         | 0.004713 seconds

Я бы сказал, что в 99% случаев использовать [NSMutableArray array] это просто прекрасно. Если вы знаете фактический размер результирующего массива, однако, не повредит использовать [NSMutableArray arrayWithCapacity:] либо.


и затем есть эта статья Питер Аттопью (который является разработчик в команде AppKit/Foundation от Apple) С несколькими проницательными критерии:

http://ridiculousfish.com/blog/archives/2005/12/23/array/


Edit (12 марта 2012):

больше информации о производительности инициализации массива из http://darkdust.net/writings/objective-c/nsarray-enumeration-performance

[...] я [=>DarkDust] также хотел знать, отличается ли производительность в зависимости от того, как массив был создан. Я протестировал два разных метода:

  • создайте массив C, который ссылается на экземпляры объекта, и создайте массив с помощью initWithObjects:count:.
  • создать NSMutableArray и впоследствии добавлять объекты с помощью addObject:.

[...] есть разница при выделении: на initWithObjects:count: метод быстрее. С очень большое количество объектов эта разница может стать значительно.


Edit (6 марта 2014):

подробнее о производительности инициализации массива из http://ciechanowski.me/blog/2014/03/05/exposing-nsmutablearray/:

давайте выделим новые массивы с начальной емкостью, установленной на последовательные степени двух:

for (int i = 0; i < 16; i++) {
    NSLog(@"%@", [[[NSMutableArray alloc] initWithCapacity:1 << i] explored_description]);
}

сюрприз:

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