Сколько это имеет значение, если я создаю NSMutableArray с емкостью = 3 вместо емкости = 50?

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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

EDIT: Я бы хотел добавить цитату из Дональда Кнута:

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

Ответ 3

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

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

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

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

Ответ 4

Хотя определенно не нужно использовать 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