Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 1265. #ЗаметкиНаПолях Используем Span Для Производительности. Окончание Начало Используем ReadOnlySpan вместо строки Рассмотрим пример, где нам нужно разобрать строку построчно:
public int ParseWithString()
{
  var prev = 0;
  var curr = 0;
  var rows = 0;
  foreach (char c in _text)
  {
    if (c == '\n')
    {
      curr += 1;
      var line = _text[prev..curr];
      if (line.Equals(Environment.NewLine))
        rows++;
      prev = curr;
      continue;
    }
    curr++;
  }

  return rows;
}

В первом примере мы используем строки. Мы пытаемся определить, сколько пустых строк в нашем файле. Текст хранится в строковой переменной _text. Мы перебираем каждый символ строке, если находим символ новой строки, с помощью Substring() проверяем предыдущую строку. Если эта строка пустая, увеличиваем счётчик. Ключевым моментом здесь является то, что Substring() создаёт строку в куче. Сборщику мусора потребуется время, чтобы уничтожить эти строки. Теперь тот же процесс с использованием Span:
public int ParseWithSpan()
{
  var textSpan = _text.AsSpan();
  var prev = 0;
  var curr = 0;
  var rows = 0;
  foreach (char c in textSpan)
  {
    if (c == '\n')
    {
      curr += 1;
      var slice = textSpan[prev..curr];
      if (slice.Equals(Environment.NewLine, StringComparison.OrdinalIgnoreCase))
        rows++;
      prev = curr;
      continue;
    }
    curr++;
  }

  return rows;
}
Здесь процесс такой же, за исключением того, что мы не создаем дополнительные строки. Мы преобразуем текстовую строку в ReadOnlySpan, вызывая метод AsSpan(). Кроме того, вместо Substring() мы используем метод Slice, который создаёт ReadOnlySpan, представляющий подстроку. В этом случае в куче ничего не выделяется. Вспомним, что сборка мусора напрямую влияет на производительность приложения. Используя ReadOnlySpan вместо строк везде, где возможно, мы можем сильно повысить производительность приложения. ReadOnlySpan поддерживает множество функций, знакомых по работе со строками: Contains(), EndsWith(), StartsWith(), IndexOf(), LastIndexOf(), ToString(), Trim() и т.п. Тестирование Оценим результаты теста производительности двух примеров выше: ParseWithSpan - 23.55 us, без аллокаций. ParseWithString - 36.12 us, аллоцировано 70,192 B Результаты ожидаемы. Span работает быстрее и не выделяет дополнительной памяти (но см. ограничения в предыдущем посте). Итого Использование Span повышает производительность. Важно отметить, что команда разработчиков .NET активно использует Span во внутренних библиотеках и максимально упрощает их использование для разработчиков. Команда .NET уже имеет поддержку Span<T> для DateTime, TimeSpan, Int32, GUID, StringBuilder, System.Random и многих других типов. Важно понимать, как использовать Span, потому что они будут больше и больше присутствовать в будущем коде .NET и в некоторых случаях могут стать стандартом. Источник: code-maze.com/csharp-…formance