tgoop.com/csharp_gepard/128
Create:
Last Update:
Last Update:
SkipLocalsInit #скорость
Мы часто используем Span
для ускорения сборки строк - создаём буфер на стеке, складываем туда кусочки будущей строки (чтобы не плодить промежуточные), а потом превращаем всё это в строку. Пример с ValueStringBuilder будет выглядеть следующим образом:
public string MyMethod() {
Span<char> buffer = stackallock char[1024];
var vsb = new ValueStringBuilder(buffer);
...
}
Это работает быстро, но можно сделать быстрее. В данном случае, местом ускорения будет создание буфера. В платформе есть правило - каждая переменная перед использованием должна быть инициализирована. В данном случае, платформа осуществляет инициализацию
Span
, то есть заполняет его элементы значениями по умолчанию. Это достаточно ресурсоёмкая операция (см. Span против SpanSkipInit на бенчмарке), которую мы можем не делать, воспользовавшись атрибутом SkipLocalsInit. Атрибут
SkipLocalsInit
, применённый к методу, заставляет компилятор не использовать инициализацию локальных переменных этого метода. Важно понимать, что это не безопасная штука, так как в созданной переменной могут содержаться значения из памяти, которые были в памяти до этого. Именно поэтому, применение атрибута SkipLocalsInit
требует объявить всю сборку как unsafe
.Я бы не стал использовать этот атрибут в обычном коде, но для библиотечного кода (который, надеюсь, обложен тестами) этот подход может весьма существенно ускорить работу с промежуточными буферами.
Также, немаловажно то, что чем больше буфер, тем более выгодно брать его из
ArrayPool
. Это отчётливо видно на бенчмарке: буфер размером более 4096 char'ов уже стоит брать оттуда. Это понятнее для разработчиков и не требует применения unsafe
.Больше подробностей о том, как работает инициализация в C# с
SkipLocalsInitAttribute
, есть тут и тут.Код бенчмарка в комментариях.
P.S.: Если же мы хотим пропускать инициализацию модно и молодёжно, не помечая сборку как unsafe, мы должны использовать
Unsafe.SkipInit
.BY C# Heppard

Share with your friend now:
tgoop.com/csharp_gepard/128