Обновить

Комментарии 28

Поддержка запуска одиночных .cs файлов звучит интересно и перспективно

Ещё бы каким то образом рефлексию в aot завезли

В Native AOT есть рефлексия! Но только ее урезанная версия, например typeof и Enum.Parse<T> будут работать, эти данные сохраняются. Это просто статические метаданные, они нужны банально для работы BCL.

Впрочем речь здесь явно не об этом, поэтому стоит упомянуть, что это невозможно, это логически невыполнимо. Native AoT прекомпилирует все методы и большинство метаданных удаляется, в этом весь ее смысл. Также как в C++ не может быть рефлексии, при ahead of time сборке в C# ее также не может быть. Рефлексия следствие JiT компилятора и везде где есть рефлексия есть JiT (ну или интерпритация)

Почему вы так уверены, что рефлексия не может существовать в нативе?

Есть статическая compile-time рефлексия, она реализуется генераторами в том же C# без проблем. А вот runtime рефлексия требует переписывание кода в процессе работы приложения, что требует виртуальную машину. Это ведь крайне банальная логика

Нет, необязательно переконструировать код "на лету" при помощи "большого брата" в виде JVM или подобного. Просто будет это довольно медленно (в тех моментах где рефлексия используется только, ведь для остальных компонентов она может просто не сохраняться), ведь рефлексия довольно увесистая и спагетти-видная.

А в go у нас где jit? Есть рефлексия и там натив

В go compile time рефлексия, это просто метаданные. В C# runtime рефлексия (RTTI). C# поддерживает статическую рефлексию в native aot уже!

В общем ваши слова не противоречат моим, а мои не противоречат вашим. Было бы проще, если бы немного внимательнее читали написанное

Что значит в go рефлексия compile time? Я может что-то путаю, но рефлексия это по определению та вещь которая происходит во время выполнения. То есть runtime. И в go именно такая. Го сохраняет метаданные и ты во время выполнения смотришь их и работаешь с ними. Рефлексия не обязывает иметь виртуальную машину как и переписывать свой код. Рефлексия по определению говорит о модификации приложения во время выполнения.

Как пример в go вы просто с помощью пакета reflection можете посмотреть теги у структуры и модифицировать поля этой самой структуры, или же создать функцию, или узнать информцию о типе или полях структуры и так далее. Никакой compile time "магии" тут нет. Обычные метаданные

Мне кажется что люди во многом недооценивают важность этого релиза

Выделение коллекций на стеке это game changer. Многие думают, "когда мне вообще нужно выделять такие буферы, это редкость? Да и есть ArrayPool для этого", но здесь речь не только про массивы, как можно подумать. RyuJiT научился аллоцировать на стек и сами объекты, те же делегаты(да, делегаты в некотором смысле коллекции) или Enumerator могут быть стек аллоцированными. И список будет только расширяться.

И тут стоит обратить внимание, что это используется везде в BCL, от этих оптимизаций выигрывает огромная часть стандартной библиотеки, давая бесплатный прирост производительности почти везде.

Фантастика! Я ждал этого ещё со времён анонса .NET9.

Когда этот барьер наконец-то преодолен, это открывает множество возможностей для оптимизаций в будущем. CLR догоняет JVM с огромной скоростью. Реальный список оптимизаций просто километровый, советую почитать официальные статьи на тему.

И мы уже знаем о планах runtime async и discriminated Unions в .NET11! Когда я начинаю думать "ну куда дальше", выходит Мэдс и предлагает новый game changer.

В общем бэнгер, а не релиз, закрывает старые гештальты. Вымирающий пример случая, когда Microsoft сделала что-то как надо

Я почему то думал что такая очевидная вещь уже была добавлена как часть оптимизации, но оказалось что прямо киллерфича какая то

CLR догоняет JVM с огромной скоростью.

Угу, догоняет, но уже по второму кругу

. CLR догоняет JVM с огромной скоростью

Я джвадцать лет этого ждал =)

Только не понятно небольшие размеры массивов это какие? 3 элемента ок, а 4 уже нет? Где эта грань что то я пока не понимаю. Как и каких типов это касается, судя из статьи только примитивных

Это касается ссылочных типов тоже, но на пользовательских классах может сломаться escape-analysis и JiT решит, что выделять на стеке небезопасно. "Небольшие размеры" очень грубо это около 10000 элементов. В целом не сомневаюсь, что в .Net11 список сильно расширится.

Аллоцировать массивы на стек можно было ещё в .Net9, но это касалось только знаковых примитивов и часто не срабатывало, поэтому и хайпа избежало. Сейчас это полноправная фишка

Причина в ограничении размера в том, что стек ограничен в размере операционкой, около 8Мб. Я здесь уже спекулирую, но я думаю на кучу уходят объекты, которые должны попасть в Large object heap, а это 80 килобайт

stackallock существует все таки сильно дольше, чем net9

stackalloc это явная ref struct, а здесь на стек отправляется стандартный int[], большая разница

В bcl заменились переписывать на stackallock?

А чего догонять в jvm? Там же все отстаёт от дотнета всегда, там до сих пор даже нельзя стек использовать для своих типов данных

BCL написан через Span и ArrayPool во многом, но делегаты, и перечислители так заменить было нельзя (и ещё ряд объектов, так сходу не вспомню). Больше всего счастливо от этих изменений LINQ, хотя у них были ещё свои оптимизации сверху, они добавили больше реализаций перечислителей для частных случаев в цепочках.

И вы не плюйтесь на JVM, она в разработке намного дольше CLR. JiT научился грузить массивы на стек, но Java могла так уже очень давно и даже больше. Из-за отсутствия структур может показаться, что все выделяется на куче, но в реальности как раз JVM может выделять ваше классы на стеке, если считает что это безопасно.

C# производительный за счёт языковых фич, за счёт очень низкоуровневой библиотеки и штук вроде async await и true generics. Java имеет ужасный дизайн языка, но сама JVM очень крутая технология. Даже с точки зрения самого банального — инлайнинга

Впрочем команда .Net в последние годы выпускают больше оптимизаций, чем любой другой язык, так что этот разрыв стремительно сокращается и в некоторых областях CLR действительно начала выигрывать, что до недавнего времени было не так

Но разве приложения на джаве не жрут уже со старта больше памяти, чем дотнетовые?

И если jvm когда-нибудь выигрывала в производительности за счёт оптимизаций на уровне JIT, то почему на ней нет популярных игровых движков? И даже тот же майнкрафт переписали на плюсы

Так ведь и на C# нет популярных игровых движков, Unity компилирует C# в C++ код под капотом, он вообще не использует CLR даже в debug режиме, шарпы там не нативные. И использует его юнити потому что IL удобный и синтаксис простой, а не потому что производительность.

В C# есть очень мощный контроль, можно писать через указатели если нужно и стандартная библиотека этим пользуется. Там все оптимизировано вусмерть, часть вообще написана на C. У джавы ситуация другая, она не даёт программистам инструментов, но JVM берет эту ответственность за себя и решает за программиста где и что она будет оптимизировать.

Если очень просто, C# будет производительней и дешевле по памяти, если его реально оптимизировать, но обычный "просто рабочий" код высока вероятность будет лучше и дешевле по памяти на Java. Что мы собственно и видим со стандартным стеком.

Il2cpp появился не сразу в юнити.

И при il2cpp все равно используется CLR. Там даже рефлексия доступна (ограниченно, как и в любом AOT).

Мне кажется, что unity использует dotnet не только из-за простоты IL (как будто джавовый байткод сильно сложнее), а именно из-за структур. Потому что можно просто взять и написать кучу своих типов на стеке, - быть уверенными что они точно будут на стеке: не бояться что GC захлебнется, а ещё гонять их в плюсы (и обратно) не боясь какого-нибудь смещения кучи. А не надеяться на чудоJIT.

Кстати, что в BCL написано на C?

Например Array.Sort написан на C. Или по крайней мере был написан, так сразу с головы тяжело сказать.

Да, в шарпе больше контроля, Шарп крутой. Но это не вина JVM и не заслуга CLR, это вина самого языка

>Все приложения на основе файлов по умолчанию нацелены на native AOT-компиляцию и поддерживают публикацию в собственных исполняемых файлах с помощью dotnet publish

Зачем тратить время и память на AOT? Это же фича в первую очередь для скриптов, как аналог PowerShell

"собери сейчас, расшифруй потом" - вот это подстава, конечно. даже не задумывался об этом((

А кому это будет надо когда можно будет расшифровать?

А где конец этим новшествам? Каждый год проект переписывать на новой версии c#? Ещё на предыдущей не успели переписать.

Разве кто-то заставляет?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
pvs-studio.ru
Дата регистрации
Дата основания
2008
Численность
51–100 человек
Местоположение
Россия
Представитель
Андрей Карпов