Comments 8
Начало - отличная статья о том, как можно оторвать ногу, лишь слегка дунув на неё.
Благо, потом немного образумились.
Так как ссылочный тип может находиться только в стеке, он не может быть членом класса и ему нельзя присвоить нессылочную переменную. Ссылочный тип может содержаться только внутри другого ссылочного типа.
Здесь некорректный по смыслу перевод. Ссылочный тип - это тот, который требует объекта в куче (то есть class или interface). ref struct - это принципиально другой вид типов, при этом адекватный перевод на русский язык до сих пор не устоялся. Более того, ref struct - это тип, который не может попасть в кучу.
Проблема такого подхода в том, что теперь мы имеем дело с пятью новыми буферами переменной длины. .NET распределяет для них новую память, а GC отслеживает их. Это медленно и занимает много памяти. Особенно проблематично это в циклах, и при этом более активно может задействоваться GC, ещё больше замедляя приложение.
Опять же, не надо сгущать краски: эфемерные поколения не столь дороги. А альтернативные варианты могут потребовать гораздо больше нагрузки на программиста при написании, и они более хрупкие при поддержке.
Иногда (именно иногда, а не всегда) важна не только дороговизна, но и стабильность времени обработки для софт‑реалтаймов во всяких играх, обработках видео/аудио и подсветочках. Потому что, по факту, в зависимости от окружения и фаз луны, это повышает вероятность того, что GC проснётся и начнёт мешать этому самому реалтайму. Даже когда «вроде как тут только 0 поколение и в 1 ничего не уходит». Не тормозами, а тем, что, например, все кадры обрабатываются 10–15 мс, но иногда, редко‑редко, 18 мс — и звук уже щёлкает и прерывается. Потому что успевать надо за 15 мс.
Но это узкие случаи, в большинстве сценариев верно ровно то, что Вы описали: усложнение, удорожание поддержки и повышение вероятности багов.
В Unity у Span нет Split. Может не во все версии еще завезли?
Безопасные операции zero-copy на C#