Нюансы 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