Насколько важно, если я создаю NSMutableArray с емкостью = 3 вместо емкости = 50? - PullRequest
10 голосов
/ 21 августа 2009

Интересно, сильно ли это влияет на производительность или потребление памяти? Мне нужен NSMutableArray, и в начале я могу только догадываться, сколько объектов будет добавлено. Может быть, от 3 до 5. Поэтому я создаю это так:

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

Что именно здесь происходит, например, при создании его с емкостью 3, а не 50? Было бы плохой идеей создать его с емкостью 1, зная, что будет не менее 20 элементов? Или это не имеет значения, чтобы принять некоторые головные боли? У меня около 10 таких массивов в моем приложении, и все они должны загружаться при запуске.

Ответы [ 5 ]

7 голосов
/ 21 августа 2009

initWithCapacity приведет к тому, что NSMutableArray предварительно выделит место для этого количества элементов.

Загрузка большего количества данных в ваш NSMutableArray сверх этой емкости приведет к NSMutableArray перераспределению базовой памяти. Это перераспределение также потребует копирования всего массива из старого (меньшего) выделения в новое (большее). Таким образом, существует снижение производительности за то, что это число слишком мало, но не слишком много.

Указание емкости, большей, чем та, которую вы фактически используете, тратит впустую память, поскольку будет выделена память для элементов, которые никогда не будут использоваться.

Я бы порекомендовал, чтобы, если вы знаете, что размер вашего массива обычно не превышает N элементов, вызовите initWithCapacity:N. Допустимо снижение производительности на NSMutableArray больше, чем N, и это штраф, который вам не придется платить за те массивы, которые не превышают этот предел.

6 голосов
/ 21 августа 2009

Это не имеет большого значения, если вы не говорите об экстремальных повторениях или огромных массивах. Не стоит пытаться оптимизировать, пока это не станет настоящим узким местом.

РЕДАКТИРОВАТЬ: Я хотел бы добавить цитату от Дональда Кнута:

Преждевременная оптимизация - корень всего зла.

3 голосов
/ 21 августа 2009

Есть теоретический ответ и практический ответ. Теоретически, установка большей емкости может изменить стратегию выделения и хранения для массива (хотя внутренне она называется NSArray, структура немного сложнее).

С практической точки зрения массив будет перераспределяться по мере необходимости, и с числами, о которых вы говорите, я сомневаюсь, что будет какая-то разница. Я мог бы сделать arrayWithCapacity, если бы знал, что буду помещать тысячи и тысячи элементов. 3 против 50 по сути бессмысленны.

Лучшее использование «withCapacity», с моей точки зрения, это просто предоставление очевидного крючка для подвешивания ваших предположений, чтобы вы могли (например) иметь в коде документацию о чем-то, что вы позже захотите утверждать. но это ни в коем случае не требуется.

С практической точки зрения, лучшее использование вашего времени - даже не думать о проблеме.

0 голосов
/ 10 мая 2018

Можно проверить этот вопрос: В чем преимущество использования arrayWithCapacity


Способность может помочь понять код как часть неявной документации. И при инициализации NSArray указание ожидаемого количества не имеет различий в производительности - измеренные значения времени практически равны и находятся в пределах статистической неопределенности.

Согласно objc.io: https://www.objc.io/issues/7-foundation/collections/


Изменяемые массивы расширяются по мере необходимости; numItems просто устанавливает начальную емкость объекта.

Обсуждение Apple Doc не вдохновило.

https://developer.apple.com/documentation/foundation/nsmutablearray/1415811-initwithcapacity?language=objc

0 голосов
/ 07 сентября 2016

Хотя использование initWithCapacity:, как и другие, упомянутые здесь, определенно не помешает, вам следует проверить это исследование о производительности инициализации массива от Бартоша Цехановского:

Начальная емкость почти не имеет значения

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...