English version is below.
Продолжаю сравнивать методы string и ReadOnlySpan<char>.
Метод Split работает на 46% – 64% быстрее в ReadOnlySpan<char>. Использование метода MemoryExtensions.Split позволяет работать со структурой Range, массив которых можно создать в стеке:
Span<Range> ranges = stackalloc Range[str.Length];
str.AsSpan().Split(ranges, separator);
Методы ToLower и ToUpper также работают на 43% – 45% быстрее в ReadOnlySpan<char>. И опять же, это преимущество достигается за счёт отсутствия аллокаций в куче:
Span<char> destination = stackalloc char[str.Length];
str.AsSpan().ToLower(destination, CultureInfo.InvariantCulture);
Производительность метода CopyTo практически одинаковая — разница составляет всего 3% в пользу ReadOnlySpan. Однако важно учитывать, что массив, в который будет скопирована строка, должен быть заранее проинициализирован. Это можно сделать как в стеке с помощью stackalloc, так и в куче с помощью оператора new, что может влиять на производительность:
// Вариант 1
Span<char> destination = new char[str.Length];
str.CopyTo(destination);
// Вариант 2
Span<char> destination = stackalloc char[str.Length];
str.CopyTo(destination);
Метод Replace в ReadOnlySpan<char> работает на 75% быстрее, чем в string. Это очевидно связано с отсутствием аллокаций при использовании ReadOnlySpan — результат замены сохраняется в отдельный Span:
Span<char> destination = stackalloc char[str.Length];
str.AsSpan().Replace(destination, oldChar, newChar);
👩💻 Код и результаты
🖥 String and Span comparison. Part 3. CopyTo, Split, Replace, ToLower, ToUpper
I continue to compare the string and ReadOnlySpan<char> methods.
The Split method works 46% – 64% faster with ReadOnlySpan<char>. Using the MemoryExtensions.Split method allows to work with Range. An array of ranges can be created on the stack:
Span<Range> ranges = stackalloc Range[str.Length];
str.AsSpan().Split(ranges, separator);
The ToLower and ToUpper methods are also 43% – 45% faster with ReadOnlySpan<char>. Again, this comes from avoiding allocations on a heap:
Span<char> destination = stackalloc char[str.Length];
str.AsSpan().ToLower(destination, CultureInfo.InvariantCulture);
Method CopyTo has almost the same performance — ReadOnlySpan is only 3% faster. However, it's important to note that the destination array should be pre-initialized. This can be done either on the stack using stackalloc or on the heap using the new operator, which can affect performance:
// Option 1
Span<char> destination = new char[str.Length];
str.CopyTo(destination);
// Option 2
Span<char> destination = stackalloc char[str.Length];
str.CopyTo(destination);
Method Replace in ReadOnlySpan<char> is 75% faster than in string. Again, this is due to the absence of heap allocations when using ReadOnlySpan:
Span<char> destination = stackalloc char[str.Length];
str.AsSpan().Replace(destination, oldChar, newChar);
👩💻 Code and results

