Емкость списка по умолчанию
Какова емкость списка по умолчанию?
8 ответов
Фактически, он начинается с Capacity 0. Когда вы добавляете первый элемент, текущая реализация выделяет емкость 4. После этого емкость продолжает удваиваться, если необходимо расширение, чтобы гарантировать амортизированную операцию O(1).
Имейте в виду, что это текущее поведение. Вы не должны полагаться на это, чтобы иметь место. Это должно продемонстрировать текущее поведение:
List<int> list = new List<int>();
int capacity = list.Capacity;
Console.WriteLine("Capacity: " + capacity);
for (int i = 0; i < 100000; i++)
{
list.Add(i);
if (list.Capacity > capacity)
{
capacity = list.Capacity;
Console.WriteLine("Capacity: " + capacity);
}
}
Почему бы тебе просто не попробовать?
Console.WriteLine("Default capacity of a List: " + new List<int>().Capacity);
Этот ответ будет работать на всех версиях.NET, имеющих список. На моей версии это бывает 0.
В соответствии с примером в документации MSDN без параметров конструктор, начальная емкость списка создается с:
List<string> x = new List<string>();
равно 0. Насколько я могу судить, это не задокументировано как гарантия и не задокументирована политика изменения размера (т. е. в настоящее время она может удваиваться с минимумом 4, но в.NET 5.0 она может утроиться с минимумом 128.) Вы не должны полагаться на это поведение, в основном.
Емкость списка по умолчанию составляет 4 элемента (после вставки исходного элемента, в противном случае он имеет размер 0)
var list = new List<int>();
list.Add(1);
Assert.AreEqual(4, list.Capacity);
По умолчанию емкость равна 0, но если вы создадите пустой список [ List1 ], как показано ниже. Если в созданном вами списке есть элементы в [ List2 ], как показано ниже, количество добавляемых вами элементов становится больше N, чем 2. Объем по умолчанию варьируется.
List<int> List1 = new List<int>(); //count=0, capacity=0
List<int> List2 = new List<int>(){ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; //count=11, capacity=16
При добавлении элементов типа Array разработчики расширили массив с помощью метода ReSize. Работало очень медленно. При разработке типа List емкость была в некоторой степени увеличена. Это соотношение рассчитано как N выше 2.
Если в список добавляется больше, чем количество членов, текущая емкость удваивается. Емкость не уменьшится, если вы удалите некоторые значения из списка. Емкость только увеличивается, а не уменьшается. Даже метод Clear на это не влияет.
Емкость следует использовать, если вы примерно знаете, сколько предметов вы хотите сохранить в Списке (или в Стеке, или в Очереди).
В этом случае вы избежите копирования памяти. Копирование памяти происходит из-за того, что под капотом списки (стеки и очереди) полагаются на массив для хранения своих элементов. Этот размер массива соответствует вашей емкости, но он не совпадает с размером списка. Поскольку размер списка должен быть больше размера массива, реализация List будет выделять больший массив (в 2 раза, а может быть и меньше) и будет копировать все элементы из старого массива в новый плюс новые добавленные элементы.
Итак, если вы знаете, что в вашем списке может быть, скажем, от 50 до 60 элементов, создайте список с емкостью 60, и никакого освобождения памяти не произойдет.
Примечание: похоже, сборщику мусора не придется очищать старые массивы.
Все это находится в одной строке, чтобы обеспечить способность хранить другой элемент:
int num = this._items.Length == 0 ? 4 : this._items.Length * 2;
Получил это из mscorlib 4.0.0.0 в разобранном виде - конечно, как сказал Джон, нельзя гарантировать, что это не изменится в будущем (пока оно все еще остается на 0, 4, 8, 16...).
Конечно, вы можете установить его самостоятельно, так что это может быть 3, 9, 27 и т. Д.
следует ли вам использовать этот подход, чтобы гарантировать, что вся необходимая информация правильно обновляется в каждой версии.
List<string> dinosaurs = new List<string>();
Console.WriteLine("\nInit:\nCapacity: {0}", dinosaurs.Capacity);
Console.WriteLine("Count: {0}", dinosaurs.Count);
dinosaurs.Add("Deinonychus");
Console.WriteLine();
foreach (string dinosaur in dinosaurs)
{
Console.WriteLine(dinosaur);
}
Console.WriteLine("Capacity: {0}", dinosaurs.Capacity);
Console.WriteLine("Count: {0}", dinosaurs.Count);
dinosaurs.Add("Mamenchisaurus");
dinosaurs.Add("Amargasaurus");
dinosaurs.Add("Compsognathus");
dinosaurs.Add("Son of Compsognathus");
Console.WriteLine();
foreach (string dinosaur in dinosaurs)
{
Console.WriteLine(dinosaur);
}
Console.WriteLine("Capacity: {0}", dinosaurs.Capacity);
Console.WriteLine("Count: {0}", dinosaurs.Count);
/* In C# 11 This code example produces the following output:
Init:
Capacity: 0
Count: 0
Deinonychus
Capacity: 4
Count: 1
Deinonychus
Mamenchisaurus
Amargasaurus
Compsognathus
Son of Compsognathus
Capacity: 8
Count: 5
==>> default: 0
*/