Повышение производительности в .NET 10
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 07.10.25 09:32
Оценка: 95 (3)
Performance Improvements in .NET 10

На русском

JIT
Среди всех областей .NET наиболее значимым является JIT-компилятор (Just-In-Time, «точно в срок»). Каждое приложение .NET, будь то небольшой консольный инструмент или крупномасштабная корпоративная служба, в конечном счёте использует JIT-компилятор для преобразования кода на промежуточном языке (IL) в оптимизированный машинный код. Любое улучшение качества кода, генерируемого JIT-компилятором, оказывает комплексное воздействие, повышая производительность всей экосистемы без необходимости вносить изменения в собственный код или даже перекомпилировать C#. И в .NET 10 таких улучшений предостаточно.

Деабстракция
Как и во многих других языках, в .NET исторически наблюдался «штраф за абстракцию» — дополнительные выделения памяти и косвенная адресация, которые могут возникать при использовании высокоуровневых языковых функций, таких как интерфейсы, итераторы и делегаты. С каждым годом JIT-компилятор всё лучше оптимизирует уровни абстракции, позволяя разработчикам писать простой код и при этом получать высокую производительность. .NET 10 продолжает эту традицию. В результате идиоматический C# (с использованием интерфейсов, циклов foreach , лямбда-выражений и т. д.) работает почти так же быстро, как тщательно продуманный и отлаженный вручную код.

Выделение стека объектов
Одним из самых интересных направлений в области деабстракции в .NET 10 является расширенное использование анализа выхода за пределы метода для выделения объектов в стеке. Анализ выхода за пределы метода — это метод компилятора, который позволяет определить, выходит ли объект, выделенный в методе, за пределы этого метода, то есть доступен ли этот объект после возврата из метода (например, сохранён ли он в поле или возвращён вызывающей стороне) или используется каким-то образом, который среда выполнения не может отследить в рамках метода (например, передан неизвестному вызываемому объекту). Если компилятор может доказать, что объект не выйдет за пределы метода, то время жизни этого объекта будет ограничено методом, и его можно будет выделить в стеке, а не в куче. Выделение в стеке обходится гораздо дешевле (простое увеличение указателя для выделения и автоматическое освобождение при выходе из метода) и снижает нагрузку на сборщик мусора, поскольку объект не нужно отслеживать сборщику мусора. В .NET 9 уже была реализована ограниченная поддержка анализа выхода за пределы метода и выделения в стеке; в .NET 10 эта поддержка значительно расширена.


public partial class Tests
{
    [Benchmark]
    [Arguments(42)]
    public int Sum(int y)
    {
        Func<int, int> addY = x => x + y;
        return DoubleResult(addY, y);
    }

    private int DoubleResult(Func<int, int> func, int arg)
    {
        int result = func(arg);
        return result + result;
    }
}


If we just run this benchmark and compare .NET 9 and .NET 10, we can immediately tell something interesting is happening.

Method Runtime Mean Ratio Code Size Allocated Alloc Ratio
Sum .NET 9.0 19.530 ns 1.00 118 B 88 B 1.00
Sum .NET 10.0 6.685 ns 0.34 32 B 24 B 0.27

и солнце б утром не вставало, когда бы не было меня
Отредактировано 09.10.2025 12:25 VladD2 . Предыдущая версия .
Re[2]: Повышение производительности в .NET 10
От: SkyDance Земля  
Дата: 14.10.25 18:03
Оценка: 16 (2)
S>Preparing for the .NET 10 GC (DATAS)

DATAS еще в 9-ке был. Сомнительная фича, если честно. С одной стороны, вроде как нужна для cloud, чтобы не balloon'ить память для лучшей утилизации. С другой — как раз именно в cloud использование подобной эвристики приводит не к увеличению, а к уменьшению производительности. Иными словами, хорошо тюненые сервисы от DATAS скорее проиграют, чем выиграют.
Re[2]: Повышение производительности в .NET 10
От: SkyDance Земля  
Дата: 09.10.25 18:59
Оценка: +2
B>Вот всё мне нравится в прогрессе Корки! Одно не пойму — что же такого кривого надо было написать в .NET FW, что ни одна из этих оптимизаций не была там применена?

Это была совершенно другая команда. Люди. Программисты, если угодно.

B>Другими словами, зачем понадобилось городить аж целую несовместимую систему вместо улучшения существующей?


См. объяснение выше. Это другая команда, более грамотная, с бОльшим уровнем знаний и умений.

B> Я что, должен там позориться "извините, индусы ещё не добрались до этих багов, так что сервер будет периодически падать"??


В команде рантайма почти нет индусов. И вообще процент белого населения меня удивил

PS: чтоб два раза не вставать. Если у тебя кака "какая-то бага, до которой индусы не добрались" — иди сюда: https://github.com/dotnet/runtime

Запускай магическую команду "git clone", собирай дебаг билд, фикси баг. Заодно и поймешь, почему "индусы не добрались". Очень часто то, что люди принимают за "мелкий баг", требует весьма нетривиального теста. А иногда и исправление неочевидно.
Re: Повышение производительности в .NET 10
От: Baiker  
Дата: 09.10.25 15:23
Оценка: :)
S>Performance Improvements in .NET 10

Вот всё мне нравится в прогрессе Корки! Одно не пойму — что же такого кривого надо было написать в .NET FW, что ни одна из этих оптимизаций не была там применена?
Мелкософту понадобилась вся мощь "автоматического развешивателя спагетти на уши", чтобы хоть как-то сдвинуть интыпрайз в сторону "мы наш, мы новый кор построим".
Хотя куда более логичным решением было бы мягко перестраивать кишки FW, чтобы можно было вводить оптимизации и даже менять платформу.

Ну вот купили они Жабьи кишки (JRE), что-то там накрутили, выкатили .NET — по факту просто "запускатор + куча либ" для MSIL поверх венды. Есессно, с каким-то gate/proxy к Win32 (pinvoke). Ну что такого можно было там написать Windows-only, чего нельзя было бы вырезать и перенести на линукс? Или внедрить всякие SSE/AVX.

Другими словами, зачем понадобилось городить аж целую несовместимую систему вместо улучшения существующей? Хоже того — Кора до сих пор страдает отсутствием важных технологий — та же WPF или WinForms. Про ошибки самой Коры и говорить не буду — стало просто принятым иметь кучу багов в любом релизе.

Собственно, я потому и пишу до сих пор в FW/WPF, что мне не упёрлись эксперименты на себе самом. Так мало я страдаю как "бесплатный пациент", мой же код ещё в продакшен нести! Я что, должен там позориться "извините, индусы ещё не добрались до этих багов, так что сервер будет периодически падать"?? Увольте, мне такой забагованый, дилетантский прогресс не нужен. Лучше медленно и надёжно, чем "анализ выхода за пределы метода для выделения объектов в стеке" и банально неработающая кнопка.
Re[2]: Повышение производительности в .NET 10
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 09.10.25 15:41
Оценка:
Здравствуйте, Baiker, Вы писали:

Ну изначально там библиотеки были написаны на использование джитом. А там главное скорость компиляции, а не выполнения.
Вообще Core был нужен прежде всего для .Net Native. Это и Windows Mobile, XBOX итд
А там уже нужно было дробить библиотеки. Во многие библиотеки были вшиты нативные dll, которые не совместимы с arm.
Ну и тогда еще не было обрезания.

До линукса было еще ооочень далеко. Больше речь шла о Windows на ARM
и солнце б утром не вставало, когда бы не было меня
Re: Повышение производительности в .NET 10
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 13.10.25 09:39
Оценка:
Здравствуйте, Serginio1, Вы писали:

Еще интересная статья

Preparing for the .NET 10 GC (DATAS)
и солнце б утром не вставало, когда бы не было меня
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.