TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.76K subscribers
Post #1568 1.64K
День 1264. #ЗаметкиНаПолях
Используем Span Для Производительности. Начало
Сегодня рассмотрим Span в C#, как он реализован и как мы можем использовать его для повышения производительности.

Span<T> — это типобезопасное и безопасное по памяти представление непрерывной области памяти. Span<T> реализован как ref-структурa (подробнее о ref-структурах), которая содержит ссылку на объект T и длину для чтения. Т.е. Span в C# всегда будет размещаться на стеке, а не в куче. Рассмотрим упрощённую реализацию Span<T>:
public readonly ref struct Span<T>
{
private readonly ref T _pointer;
private readonly int _length;
}

Использование Span<T> повышает производительность за счёт размещения на стеке, т.к. сборка мусора не тормозит выполнение приложения. Операции со Span<T> аналогичны операциям с массивами: индексация в Span не требует вычислений для определения адреса памяти.

Другой реализацией Span является ReadOnlySpan<T>. Его отличие от Span в том, что индексатор возвращает ссылку на T только для чтения. Это позволяет использовать ReadOnlySpan<T> для представления неизменяемых типов данных, таких как string.

Span может использовать типы значений, такие как int, byte, ref struct, bool и enum. Span не может использовать такие типы, как object, dynamic или интерфейсы.

Ограничения
Реализация Span ограничивает его использование в коде. Объекты ссылочного типа размещаются в куче, поэтому мы не можем использовать Span в качестве полей в ссылочных типах. Также ref-структуры не могут быть упакованы, и Span нельзя использовать в лямбда-выражениях и асинхронном коде с await, а также с yield. Кроме того, т.к. мы выделяем память в стеке, мы должны помнить, что памяти в стеке меньше, чем в куче.

Span-подобный класс можно использовать в асинхронном коде. Это классы Memory<T> и ReadOnlyMemory<T>.

Примеры
Мы можем использовать Span для работы с массивами и другими типами коллекций:
int[] arr = new[] { 0, 1, 2, 3 };
Span<int> intSpan = arr;
var otherSpan = arr.AsSpan();

C# предлагает неявное приведение от T[] к Span<T>, но мы также можем вызвать AsSpan() для массивов. Как ReadOnlySpan<T>, так и Span<T> предлагают знакомые по работе с массивами функции, не выделяющие дополнительную память.

Теперь рассмотрим на аналогичный пример с List<T>:
List<int> intList = new() { 0, 1, 2, 3 };
var listSpan = CollectionsMarshal.AsSpan(intList);

Использовать Span с коллекцией не так просто, как с массивами. В этом случае мы должны использовать метод CollectionMarshal.AsSpan(), чтобы получить коллекцию в виде Span. Для этого нужно импортировать пространство имён System.Runtime.InteropServices.

Окончание следует…

Источник:
https://code-maze.com/csharp-span-to-improve-application-performance/
  • 👍 2
More from @netdeveloperdiary
  1. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  2. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  3. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  4. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  5. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  6. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
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 →