Подтвердить что ты не робот

Стоит ли инициализировать размер коллекции List <T>, если размер его разумно известен?

Стоит ли инициализировать размер коллекции List<T>, если это разумно известно?

Изменить:. В связи с этим вопросом, прочитав первые ответы, этот вопрос действительно сводится к тому, что является пропускной способностью по умолчанию, и как выполняется операция роста, удваивает емкость и т.д.? p >

4b9b3361

Ответ 1

Да, это важно, когда ваш List<T> становится большим. Точные числа зависят от типа элемента и архитектуры машины, позволяют выбрать список ссылочных типов на 32-битной машине. Каждый элемент будет принимать 4 байта внутри внутреннего массива. Список начнется с Емкости 0 и пустого массива. Первый вызов Add() увеличивает емкость до 4, перераспределяя внутренний массив на 16 байтов. Четыре Add() звонят позже, массив заполнен и снова должен быть перераспределен. Он удваивает размер, емкость увеличивается до 8, размер массива до 32 байтов. Предыдущий массив - мусор.

Это повторяется при необходимости, несколько копий внутреннего массива станут мусором.

Что-то особенное происходит, когда массив вырос до 65 536 байт (16 384 элемента). Следующий элемент Add() удваивает размер до 131 072 байта. Это распределение памяти, превышающее пороговое значение для "больших объектов" (85 000 байт). Выделение теперь больше не выполняется на куче генерации 0, оно берется из кучи больших объектов.

Объекты на LOH обрабатываются специально. Это всего лишь мусор, собранный в коллекции поколения 2. И куча не уплотняется, требуется слишком много времени для перемещения таких больших кусков.

Это повторяется при необходимости, несколько объектов LOH станут мусором. Они могут занимать память довольно долго, коллекции поколения 2 происходят нечасто. Другая проблема заключается в том, что эти большие блоки имеют тенденцию фрагментировать адресное пространство виртуальной памяти.

Это не повторяется бесконечно, рано или поздно класс List должен перераспределить массив, и он стал настолько большим, что в адресное пространство виртуальной памяти не осталось отверстия, чтобы он соответствовал массиву. Ваша программа будет бомбить с OutOfMemoryException. Обычно задолго до того, как вся используемая виртуальная память будет потреблена.

Короче говоря, установив Capacity раньше, прежде чем вы начнете заполнять список, вы можете зарезервировать этот большой внутренний массив впереди. Вы не получите все эти неудобные выпущенные блоки в кучке больших объектов и избегаете фрагментации. Фактически, вы сможете хранить в списке еще много объектов, и ваша программа работает на более компактной основе, поскольку там так мало мусора. Сделайте это, только если у вас есть хорошая идея, насколько велик список, используя большую емкость, которую вы никогда не заполните, расточительно.

Ответ 2

Это согласно документации

Если размер коллекции может быть с указанием первоначальной способность устраняет необходимость выполнить изменение размера операций при добавлении элементов в Список (T).

Ответ 3

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

Если это будет особенно большой список, и у вас есть неплохая идея о размере, это не повредит. Однако, если оценка размера предполагает дополнительные вычисления или какой-либо значительный объем кода, я бы не стал беспокоиться об этом, если вы не обнаружите, что это становится проблемой - это может отвлечь основное внимание на код, а изменение размера вряд ли вызовет производительность если это действительно большой список или вы делаете это много.