Вышла Akbura 12.0.4-beta.6. В этом обновлении я существенно оптимизировал компилятор, улучшил инкрементальную генерацию кода и добавил возможность использовать реактивные C#-выражения непосредственно в разметке.
Для тех, кто впервые слышит о проекте: Akbura это экспериментальный декларативный язык разметки и компилятор для .NET и Avalonia. Он объединяет компоненты, C#-выражения, реактивное состояние и типизированную стилизацию через AKCSS.
В этой статье хочу рассказать о двух основных изменениях: оптимизации компилятора и новом механизме привязок выражений, который можно использовать в существующих MVVM-приложениях.
Ускорение генерации кода и сокращение аллокаций
Работа над оптимизацией компилятора дала следующие результаты на проектах FeatureGallery и PurityUI:
|
Проект |
Показатель |
До |
После |
Изменение |
|---|---|---|---|---|
|
FeatureGallery |
Холодная генерация |
15,31 с |
6,06 с |
−59,35% |
|
FeatureGallery |
Аллокации |
3327,72 MiB |
1040,38 MiB |
−68,73% |
|
PurityUI |
Холодная генерация |
2,38 с |
1,78 с |
−26,50% |
|
PurityUI |
Аллокации |
941,48 MiB |
300,50 MiB |
−68,09% |
Таким образом, в FeatureGallery холодная генерация исходного кода стала примерно в 2,5 раза быстрее, а количество выделяемой памяти сократилось почти на 69%. В PurityUI аллокации уменьшились примерно на 68%.
Замеры проводились на .NET 10 в конфигурации Release, через RunGenerators, с четырьмя парными запусками процессов для каждого проекта.
Результаты относятся к оптимизациям, вошедшим в beta-6, но были получены до последних изменений в проверках синтаксиса и обновления Roslyn.
Дополнительно сравнение прошло 118 проверок на точное совпадение сгенерированного кода и диагностических сообщений.
Подробности, включая сравниваемые ревизии и условия тестирования, доступны в коммите с результатами бенчмарков.
Важно отметить, что измерялась именно работа генератора исходного кода. Полная сборка проекта и отзывчивость редактора включают дополнительные операции, а приведённые показатели памяти отражают объём аллокаций во время генерации, а не пиковое потребление памяти всего процесса.
Что изменилось внутри компилятора
Основной целью оптимизаций было сокращение повторных вычислений и количества временных объектов, создаваемых компилятором.
Вот некоторые изменения:
-
Пулинг коллекций и буферов. Добавлено повторное использование временных коллекций,
HashSet, словари диагностик, делегаты иStringBuilder. -
Сокращение LINQ-аллокаций. Убраны ненужные промежуточные объекты. Для пространств имён элементов разметки используются
SmallDictionary. -
Кеширование метаданных. Добавлено кеширование строковых представлений символов Roslyn и имён метаданных компонентов. Поиск метаданных AKCSS теперь использует общий контекст, который создаётся только при необходимости.
-
Генерация имён типов без промежуточных строк. Распространённые полностью квалифицированные имена типов записываются непосредственно в выходной код.
-
Повторное использование контекста анализа C#. Сокращена повторная работа при проверке C#-выражений и формировании семантических диагностик. Ещё немного поработал над проверками синтаксических узлов. Оказалось, что в некоторых случаях сравнение через
SyntaxKindбыстрее, чем проверка типа черезis. Проверил это на бенчмарках, а заодно посмотрел, какойILи машинный код генерируется в обоих случаях.
Все эти изменения направлены на снижение стоимости операций, которые Akbura многократно выполняет во время сборки и анализа проектов.
Улучшения Hot Reload и интеграции с редакторами
В beta-6 также улучшена работа Hot Reload, в частности сохранение совместимого состояния компонентов при обновлениях.
Также немного оптимизировал Hot Reload и AKCSS. Теперь генерируется меньше лишних членов, а при обновлении компонентов выполняется меньше ненужной работы.
Кроме того, исправлены проблемы с именами стилизованных элементов управления и обновлением замыканий команд во время Hot Reload.
Эти изменения улучшают корректность обновлений и управление ресурсами. Подробности о поддерживаемых сценариях описаны в документации Hot Reload.
Изменения коснулись и редакторов кода.
Исправлен вывод типов параметров лямбда-выражений в обработчиках событий, добавлено автодополнение для незавершённых лямбда-выражений хуков, а языковые сервисы получили поддержку нового механизма привязок выражений.
Зависимости компилятора и Workspaces обновлены до Roslyn 5.9.0.
Одновременно с выпуском пакета вышло обновление расширения для Visual Studio версия 12.0.4.19.
Оно исправляет проблему устаревших диагностических сообщений при инициализации проекта, восстановлении зависимостей и изменении контекста проекта.
Теперь открытые файлы обновляются автоматически, несохранённый текст остаётся нетронутым, а устаревшие результаты фонового анализа не могут перезаписать новые диагностические сообщения.
Ранее из-за этой проблемы ошибки могли оставаться в редакторе до тех пор, пока пользователь не закроет и заново не откроет файл.
Подробнее в описании обновления расширения.
Реактивные биндинги C#-выражений для MVVM
Одно из главных нововведений beta 6 это ${x.bind ...}.
Этот механизм позволяет использовать реактивные, строго типизированные C#-выражения непосредственно в разметке. Проверка выражений выполняется с помощью Roslyn.
Например:
<TextBlock Text=${x.bind Vm.Profile?.Name ?? "Unknown"}/>
Привязка отслеживает изменения свойств, поддерживающих уведомления об изменениях.
Если изменится Vm.Profile, подписки автоматически перестроятся для нового объекта. Если изменится Name текущего профиля, значение TextBlock.Text также обновится.
При этом повторный рендеринг компонента не требуется.
Привязки выражений поддерживают:
-
Арифметические вычисления.
-
Интерполяцию строк.
-
Условные выражения.
-
Индексированный доступ к коллекциям.
-
Отслеживание изменений свойств в цепочках доступа.
Кроме того, привязки работают с условиями утилитарных стилей AKCSS. Это позволяет управлять не только содержимым элементов, но и их оформлением непосредственно через свойства ViewModel.
Привязки являются односторонними (One-Way) и дополняют существующий механизм Avalonia ${Binding ...}, а не заменяют его.
Таким образом, бизнес-логика по-прежнему может оставаться во ViewModel, а Akbura отвечает за её отображение в интерфейсе.
Посмотреть примеры можно в Feature Gallery или в документации Expression Bindings.
Как попробовать beta 6
Для установки Akbura в существующий проект выполните:
dotnet add package Akbura --version 12.0.4-beta.6
Либо установите обновлённые шаблоны проектов:
dotnet new install Akbura.Templates::12.0.4-beta.6
Для работы потребуется .NET SDK версии 10.0.400 или новее.
Обновлённое расширение Visual Studio требует Visual Studio 2026 версии 18.9 или новее.
Рекомендую обновлять расширение редактора вместе с пакетом Akbura, чтобы версии компилятора и языковых сервисов совпадали.
В Feature Gallery уже доступны интерактивные примеры использования Expression Bindings.
Также галерея теперь поддерживает прямые ссылки на отдельные примеры и навигацию Back/Forward в браузере, благодаря чему примерами стало удобнее делиться.
Полезные ссылки
Буду рад обратной связи, особенно по новому механизму привязок выражений и производительности компилятора.
ссылка на оригинал статьи https://habr.com/ru/articles/1103390/