Разница Между Выражениями и Инициализаторами Коллекций
Вы когда-нибудь задумывались, есть ли разница между выражением коллекции:
List<int> list = [1, 2, 3];
и инициализатором коллекции:
List<int> list2 = new() {1,2,3};Давайте выясним. Для этого посмотрим, во что преобразуется каждая строчка.
Выражение коллекции:
int num = 3;
List<int> list = new List<int>(num);
CollectionsMarshal.SetCount(list, num);
Span<int> span = CollectionsMarshal.AsSpan(list);
int num2 = 0;
span[num2] = 1;
num2++;
span[num2] = 2;
num2++;
span[num2] = 3;
num2++;
Инициализатор коллекции:
List<int> list2 = new List<int>();
list2.Add(1);
list2.Add(2);
list2.Add(3);
Таким образом, выражения для коллекций ([1,2,3]) «умнее» и быстрее в том смысле, что они заранее выделяют список с точным количеством элементов, которые мы хотим добавить. Инициализатор коллекции не делает этого по одной простой причине: компилятор, согласно своей спецификации, обязан вызывать метод Add для каждого элемента в инициализаторе.
Конечно, для 3х элементов особой разницы в производительности не будет. А вот, например, бенчмарк для 17 элементов:
| Method | Mean | Allocated |
|-----------|---------:|----------:|
|Expression | 18.09 ns | 128 B |
|Initializer| 72.88 ns | 368 B |
Вопрос, почему здесь инициализатор тратит больше времени и памяти, любят задавать на собесах. Кто знает, пишите в комментариях.
Источник: https://steven-giesel.com/blogPost/fea0b033-ccf5-4197-b62c-ffd8ca6d79c7/quick-one-difference-between-collection-expressions-and-collection-initializer