dotNET / Производительность dotNET / CSharp / Performance
В прошлом месяце я писал об улучшениях производительности в .NET Core 2.1, а сегодня расскажу о двух фичах C# 7.2 — модификаторе “in” и readonly-структурах.
Рассказ, как обычно, будет коротким. Но со списком статей для дополнительного изучения :) Пара статей Сергея Теплякова и мотивировала меня написать этот краткий конспект на русском языке.
Обычно в старом добром C# параметры передаются либо по значению, либо по ссылке (с модификатором ref или out).
Недавно, в C# 7.2, добавили модификатор in
, который работает как ref
, но гарантирует, что эту ссылку не поменяют.
Ещё одно отличие — можно задавать значение по умолчанию. То есть, можно написать так:
и знать, что компилятор не даст поменять ссылку на test
в методе Test
.
Но, поскольку по факту это ref
, нельзя вызвать метод так
Для чего это полезно? Понятно, что для ссылочных типов пользу найти будет тяжеловато (если сравнивать с передачей этой ссылки по значению). Разве что более явно можно обеспечить то, что параметру ничего не присвоят в методе.
А вот сценариев, когда передаётся структура, которую нельзя менять, дополнительный бонус — можно передать её по ссылке. В этом случае будет передаваться только ссылка на структуру, что должно и экономить память и повысить скорость.
Должно, но это неточно :) Маленький нюанс — для обычной структуры будет создаваться “defensive copy”, чтобы обеспечить её неизменяемость. Поэтому…
В C# 7.2 появились readonly-структуры, гарантирующие свою неизменяемость (забудем на минутку о Reflection). Описываются они просто:
и могут содержать только readonly-поля и get-свойства. Это, само собой, хорошая фича даже просто с точки зрения улучшения качества кода.
А ещё это позволяет избежать создания “defensive copy” для структур, передаваемых с помощью модификатора in
.
И, заодно, для readonly-полей типа struct
(в исходной статье про это подробно написано, с бенчмарками).
Конечно, если “readonly” для ваших задач не требуется — можете просто всем этим не пользоваться. Но, если писать вдумчиво, “readonly” будет полезным достаточно часто.
Что касается производительности — понятно, что не всегда выигрыш от readonly struct
критичен.
Но если это активно используется, то производительность может улучшиться в разы.
А для структур в C# придумали столько вкусного, что использоваться структуры будут всё чаще.
Главное: старайтесь использовать (где это логично) readonly struct
если используете:
in
;struct
;readonly ref returns
или readonly ref locals
(об этом во второй статье Сергея).
Скажу больше — использование этих конструкций с обычными структурами значительно повышает шансы успешного отстреливания ног :)
dotNET / Производительность dotNET / CSharp / Performance