TGViewer
yet another dev yet another dev @yet_another_dev · 382 subscribers
Post #116 419
Создание массивов в C#: способы и производительность

Как создать массив в C#? Вопрос кажется простым. Но с каждой новой версией .NET появляются всё новые и новые фичи. На данный момент я знаю аж 7 способов создания массивов:

1. new T[]. Самый очевидный, простой и популярный способ создания объектов и массивов в частности. Этот оператор используется повсеместно и является основным для большинства сценариев.

2. stackalloc T[]. Выделяет память в стеке для массива заданного размера и возвращает указатель. Когда-то давно оператор stackalloc требовал использования небезопасного (unsafe) контекста. С появлением Span<T> его можно применять и без unsafe. Этот способ ограничен размером доступной памяти в стеке и при необдуманном использовании может привести к StackOverflowException.

Для небольших массивов stackalloc T[] быстрее new T[] в среднем на 20% и на 88% для больших массивов. Под небольшими массивами я подразумеваю массивы размером меньше 85 000 байт, т.е. размещаемые в куче малых объектов (SOH), а под большими – в куче больших объектов (LOH).

3. ArrayPool<T>. ArrayPool выделяет массив из пула, что минимизирует количество аллокаций памяти и уменьшает нагрузку на сборщик мусора. Массивы, возвращаемые из пула, могут быть больше запрошенного размера, например, для массива из 700 элементов будет возвращён массив длиной 1024. Использование пула полезно, для относительно больших временных массивов, которые часто создаются и уничтожаются.

ArrayPool<T> быстрее new T[] в среднем на 30% для небольших массивов и на 89% для больших массивов. Однако для массивов размером менее 300–400 байт использование пула может быть медленнее.

4. GC.AllocateUninitializedArray<T>. Этот метод создаёт массив без инициализации его элементов значениями по умолчанию. Использование этого метода может быть небезопасным, так как массив содержит неинициализированные данные. Обязательно перезаписывайте все значения в созданном массиве.

GC.AllocateUninitializedArray<T> быстрее new T[] в среднем на 15% для массивов 2048 – 85 000 байт. В остальных случаях производительность с new T[] одинаковая.

5. Array.Initialize. Позволяет создавать массивы, задавая тип во время выполнения. Например, когда тип неизвестен на этапе компиляции. Полезно для сценариев, связанных с динамической типизацией.

Производительность аналогична new T[], либо хуже.

6. InlineArrayAttribute. Относительно новая фича, появившаяся в C# 12. Позволяет объявить структуру с атрибутом InlineArray, которая будет вести себя как массив. Память для массива выделяется в стеке со всеми вытекающими ограничениями.

Быстрее new T[] в среднем на 39% для небольших массивов и на 91% для больших массивов.

7. collections expressions. Синтаксический сахар, который позволяет записать массив в виде литерала. Например,

int[] array = [1, 2, 3]

создаёт массив в куче, аналогично использованию new T[]. А конструкция

Span<int> array = [1, 2, 3]

создаёт массив в стеке, аналогично stackalloc.

Код бенчмарка и результаты тут.
  • 👍 16
More from @yet_another_dev
  1. Sep 21, 2026Опубликовал вчера ролик в одной запрещённой в России соцсети про то, как сходил на выборы.…
  2. Sep 20, 2026Мы пришли в 7:50 и очередь уже была 🥲 Пообщались с другими людьми. Многие приехали из дру…
  3. Sep 19, 2026Post #383
  4. Sep 18, 2026Последние пару недель на чат нападают боты со спамом (прикрыл стикером). Поэтому чат тепер…
  5. Sep 17, 2026Что интересного в этой статье: 1. Потрачено $120К, а агенты суммарно отработали около 3-х…
  6. Sep 17, 2026В Microsoft переписали рантайм GitHub Copilot с TypeScript на Rust при помощи агентов. Под…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →