Как использовать {массив | словарь}WithCapacity?

Когда я использую NSMutableArray или же NSMutableDictionaryЕсли я знаю количество элементов, которые я хочу вставить, или максимальное количество элементов, я обычно создаю их с arrayWithCapacity или же dictionaryWithCapacity, но мне интересно, действительно ли это помогает определить (начальную) емкость для массива / словаря?

Я не знаю, как это реализовано внутри, но я полагаю, что возможно, когда количество элементов в коллекции достигает емкости или даже приближается к емкости, коллекция может расширить свою емкость, поэтому, если я создал изменяемый массив с емкость 32, пока я поместил в нее 32-й объект, он расширится до другой емкости? Или даже если я добавлю в него 30-й объект, его емкость будет расширена, так как он думает, что будет больше объектов?

Так что, если эти методы действительно помогают, я должен использовать что-то вроде:

 *withCapacity:maxNumberOfElements * 1.5

вместо

*withCapacity:maxNumberOfElements

так что у меня будет более чем достаточно возможностей для моих объектов и не будет расширяться, когда я добавлю все объекты?

3 ответа

Решение

Это полезно, когда вы планируете заполнить коллекцию большим количеством элементов или когда вы знаете точное количество элементов, которые вы собираетесь загрузить. Изменение размера коллекции занимает циклы ЦП, поэтому изменение размера без необходимости в конечном итоге приводит к сокращению времени работы устройства от батареи.

Рассмотрим этот пример: допустим, вы собираетесь загрузить 3000 элементов в массив. Если вы выделите массив по умолчанию с пространством, скажем, для 16 элементов, массив должен будет изменить размер в восемь раз, прежде чем достигнет размера, необходимого для хранения 3000 элементов. Элементы, скопированные в начальные позиции, необходимо будет копировать каждый раз при изменении размера массива, что приводит к более 3000 дополнительных операций копирования. Когда вы знаете точное количество элементов, вы можете предотвратить копирование.

Кроме того, ваш массив не будет тратить память на элементы, которые вы не собираетесь добавлять: если вы добавите 3000 элементов один за другим, массив может вырасти до 4000 внутри в ожидании большего количества элементов; последние 1000 элементов будут потрачены впустую.

Подводя итог, вы должны инициализировать ваши коллекции с емкостью, когда вы точно знаете точный размер цели. Эта ситуация часто возникает при десериализации данных из файла или сетевого подключения. В ситуациях, когда вы не знаете размер, лучше не угадывать, и пусть инициализация по умолчанию будет проходить.

Реально говоря, если вы не создаете много массивов / словарей (по сравнению с частотой, скажем, представления страниц пользовательского интерфейса), не будет ощутимого улучшения производительности от использования ...WithCapacity, И даже в этом случае нет никакого смысла беспокоиться об этом, если у вас нет массивов / словарей с как минимум несколькими сотнями записей.

С точки зрения того, какой размер предположить, вероятно, немного (5-10%) по сравнению с окончательным размером является идеальным, но это частично зависит от того, склонны ли вы к ограничению памяти.

Если вы точно знаете, сколько записей, укажите именно эту сумму (если вы укажете что-нибудь).

Это полезно с точки зрения производительности. Когда емкость часто увеличивается, новый массив выделяется в памяти (обычно в 2 раза больше емкости текущего), и старый массив копируется в новый массив. Это может стать дорогостоящим по мере увеличения количества элементов, поэтому, если у вас есть большие массивы, емкость которых (примерно) заранее известна, рекомендуется использовать initWithCapacity. С другой стороны, если вы выделяете что-то намного большее, чем нужно, вы тратите впустую пространство, поэтому применяется стандартное предупреждение "используйте с осторожностью".

Другие вопросы по тегам