Обновить

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

Что уже работает?

не вижу ничего про модули (module, import, export), ничего связанного с корутинами (co_await, co_yield etc), consteval упомянут в скрипте в часть 1, но похоже тоже нигде больше не участвует. constinit туда же, всякие [[аттрибуты]] не замечены, explicit(bool) не замечен, синтаксис рефлексии и синтаксис контрактов - тоже не видны.

ссылка на файл

не очень понятно зачем вы целое одно предложение под спойлер спрятали. У вас в том файле кодировка сползла и похоже часть текста в windows-1251.

Для сравнения: на моей машине cl.exe компилирует мой код со скоростью ~70KB/s

Это несколько бессмысленное сравнение. Проинстанцируйте в сгенерированном коде ещё и шаблоны и скорость компиляции вырастет ещё больше. Умудритесь вычислить лексически все constexpr/consteval - получите ещё плюс. Ну и можно поэкономить на спичках убрав всякие public: public:. А вообще стоило бы замерить сколько времени занимает генерация и сравнить с компиляцие того же файла без генерации.

модули (module, import, export), ничего связанного с корутинами (co_await, co_yield etc)

модулей пока действительно нет и co_yield тоже нет, а вот co_await есть/поддерживается, правда в статье не упомянут, его надо в грамматике(в файле inp.qapdsl.h) смотреть.

consteval упомянут в скрипте в часть 1, но похоже тоже нигде больше не участвует. constinit туда же

consteval и constinit просто добавлены в списки ключевых слов, но я тщательно не проверял их работоспособность во всех контекстах.

всякие [[аттрибуты]] не замечены

аттрибуты должны вроде полностью поддерживаться, смотрите файл inp.qapdsl.h#L95

explicit(bool)

интересный зверь.

синтаксис рефлексии и синтаксис контрактов - тоже не видны

рефлексии пока нет, добавил про это в статью, а вот контракты я очень сильно старался сделать полностью, но всё равно нашлись 20% сценариев где они не парсятся пока.

не очень понятно зачем вы целое одно предложение под спойлер спрятали. У вас в том файле кодировка сползла и похоже часть текста в windows-1251.

там было 6 пунктов и я все их устранил пока готовил статью, а спойлер остался. виноват, замучил всех спойлерами наверно. надо бы его убрать. сейчас уберу. всё убрал.

У вас в том файле кодировка сползла и похоже часть текста в windows-1251.

так и есть. сейчас пойду править.

Проинстанцируйте в сгенерированном коде ещё и шаблоны и скорость компиляции вырастет ещё больше

наоборот же должно быть? когда это от инстанцирования шаблонов скорость компиляции росла?

Умудритесь вычислить лексически все constexpr/consteval - получите ещё плюс

хм, заманчивое предложение, попробую.

Ну и можно поэкономить на спичках убрав всякие public: public:

ха, вот это баг, там между ними объявления полей должно быть, но я не тот файл подложил когда "cl /EP" вызывал и в итоге во всём файле поля внутри сериализуемых структур отсутствуют. забавно. нужен план как это пофиксить... обновить и файл и результаты его парсинга в статье что-ли? да, наверно так и надо сделать. спасибо за находку!

А вообще стоило бы замерить сколько времени занимает генерация и сравнить с компиляцие того же файла без генерации.

тут где-то путаница, что вы подразумеваете под генерацией? у меня в моей проге(QapCppFront) сначала дерево строится, а потом обходится и две метрики на выходе: время строительства и время обхода-генерации json-отладочного представления. с трудом понимаю что вы ходите и с чем сравнить. на ум только приходит идея что вы хотите запустить cl.exe без генерации кода, но это вряд ли возможно.

спасибо за ценный комментарий!

наоборот же должно быть? когда это от инстанцирования шаблонов скорость компиляции росла?

скорость компиляции растет тем больше чем меньше компилятор занимается деятельностью. инстанциорование шаблонов (aka мономорфизация) и проверка всяких ODR в большинстве языков реализующих подобные механизмы шаблонов довольно медленные - рекурсивное инстанцировние, поиск шаблонов, подстановка ссылок на инстанции шаблонных функций или инлайнинг, проверка коллизий, всякие проверки границ типов через те же концепты - всё это довольно не быстрая история и обычно требующая нескольких дополнительных проходов по AST. Поэтому если вы самостоятельно проведёте подобную мономорфизацию, то компиляция в теории может ускориться при определённых сценариях - компилятору не нужно будет гадать какую функцию позвать и останется только прокинуть нужные аргументы.

тут где-то путаница, что вы подразумеваете под генерацией?

Насколько я понял вы берёте некоторый код, прогоняете его сквозь свой фронт и не выходе получаете некоторое собственное представление AST, которое можно скормить дальше по пайплайну в обычный компилятор (пока не напишите свой). Вот этот шаг от обработки через ваш фронт и до этапа когда оно попадает в компилятор я и назвал генерацией. Сравнивать предлагал с аналогичным кодом, который бы писался на плюсах ручками.

Насколько я понял вы берёте некоторый код, прогоняете его сквозь свой фронт и не выходе получаете некоторое собственное представление AST

На выходе пока обычный JSON, и дальше он никуда(ну кроме как на проверку глазами) не идёт, хотя может в теории, но загонять его ещё куда-то мало смысла как по мне, т.к весь смысл в том чтобы обходить дерево из которого он строится прямо на стороне С++ — это красиво/удобно/мощно/всё_собственно_для_этого_и_делается.

которое можно скормить дальше по пайплайну в обычный компилятор (пока не напишите свой)

можно, но эта стадия не реализована и крайне маловероятно что будет когда-то реализована, т.к я не планирую просто так выходить со стороны C++ на другой ЯП для того чтобы делать семантический анализ там.

Вот этот шаг от обработки через ваш фронт и до этапа когда оно попадает в компилятор я и назвал генерацией

ясно, но как я уже сказал в предыдущем комментарии у меня стадии чётко разделены и время измеряется для каждой стадии отдельно. то есть я уже в статье меряю время строительства дерева отдельно от того что вы называете генерацией.

Сравнивать предлагал с аналогичным кодом, который бы писался на плюсах ручками.

вот это я опять не понимаю что вы тут имеете ввиду: какой ещё аналогичный код? о каком коде речь? да ещё и ручками? единственное что приходит на ум когда мне говорят что я что-то не пишу ручками — это выхлоп от генератора парсеров, но причём тут он?

Поэтому если вы самостоятельно проведёте подобную мономорфизацию, то компиляция в теории может ускориться при определённых сценариях - компилятору не нужно будет гадать какую функцию позвать и останется только прокинуть нужные аргументы.

скорее не согласен, чем наоборот. считаю что это только замедлит компиляцию, т.к компилятору придётся парсить больше текста + ему всё равно надо проверять все типы которые мы подставим в шаблоны при специализации на совместимость точно также как если бы он их вывел сам. как по мне так реализация вывода типов в компиляторе — очень дешёвая штука и там даже поиск не нужен, т.к тип выражения почти всегда известен на этапе семантического анализа при компиляции. так мне показалось когда я делал реализацию auto в другом своём компиляторе. может конечно с инстанцированием всё иначе, хз, никогда его не делал пока.

вот это я опять не понимаю что вы тут имеете ввиду: какой ещё аналогичный код?

я похоже не правильно понял назначение того кода. вопрос снят.

 считаю что это только замедлит компиляцию, т.к компилятору придётся парсить больше текста 

когда код линейный и не имеет скрытой дополнительной семантики (ODR check, SFINAE, conсepts, type traits, inhetance), то и парсинг такого кода становится максимально линейным и сокращается количество проходов. Паскаль, Go, V, Odin и Jai - по этой причине имеют безумно быстрые компиляторы, которые начинают страдать в основном только на проходах оптимизации. Odin и Jai способны скомпилировать полмиллиона строк кода за секунду на одном ядре - без кэширования артефактов, без инкрементальных сборок. Так что нет, больше простого плоского кода не добавляет проблем компилятору и позволяет агрессивно распараллеливать компиляцию. Любой полиморфизм и рефлексия в языках заставляют компиляторы делать крюк и именно подобный код замедляет компиляцию, по крайней мере на этапе парсинга. Похожая проблема возникает кстати и на этапе линковки, когда заглушки вызовов начинают прибивать к реальным вызовам функций.

Так что нет, больше простого плоского кода не добавляет проблем компилятору и позволяет агрессивно распараллеливать компиляцию

в общем виде ваша логика понятна и я с ней согласен, но у нас тут С++, и в нём ручная специализация шаблонов — это дополнительный текст, проверки и тормоза. если бы мы могли инстанцировать шаблоны не шаблонным кодом, а сразу в промежуточное представление - у нас была бы надежда на ускорение, но так нет. без шансов. ну ладно, хорошо, завтра проверю на деле вашу теорию ускорения компиляции примирительно к С++ на разных компиляторах, если время найду.

Odin

посмотрел их компилятор и примеры, интересная штука. парсинг вручную делают на С++. обмазались макросами в заголовочнике и довольные ходят. а ещё у них eval-а нет. а без него ЯП делать сейчас — это большая ошибка как мне кажется.

если бы мы могли инстанцировать шаблоны не шаблонным кодом

ну вот собственно про подобное инстанцирование и говорил, да. Но да, ручками разворачивать боль.

 парсинг вручную делают на С++

там ещё куча арен для более линейных аллокаций и какие-то кастомные рекурсивные мьютексы и система асинхронных тасок.

макросами в заголовочнике

там ещё и интернирование через #include "file.cpp". Очень много разных нестандартных приколюх, вписывающихся в идею языка - делать проще, а не заумнее.

Если под eval подразумевается compile time исполнение то видимо Билл не осилил его доставить и может быть что-то будет к релизу 1.0 в январе следующего года. У Jai - языке побратиме - точно есть довольно мощная система макросов, которая позволяет запускать почти произвольный код в CT, но у него компилятор пока в закрытой бете.

ООО коллега, я тоже пишу свой dsl, и пишу серию статьей об этом.

Если вы гоните за производительностью попробуйте DFA(детерминированный конечный автомат). Да сначала кажется как это штука которую мы писали в универах на тетрадке вообще может пригодиться. Но конкретно в моем dsl это дало выигрыш в производительности 15% и уменьшение аллокации памяти 8%(кстати так как я писал dsl на c#, там уменьшение аллокации памяти напрямую влияет на производительность поэтому ваш выигрыш на c++ может быть меньше)

А сорян, решил все же посмотреть ваш репозиторий на всякий случай и вы уже используете DFA, ну тогда оставлю коммент для продвижение, если на хабре такое работает.

DFA(детерминированный конечный автомат).

Синтаксис плюсов тянет с собой очень много семантики, DFA разве, что на токенизацию можно написать, но она не сказать чтобы сильно тормозная и в том виде, что есть. Парсинг и построение AST - вот где медленная собака зарыта. Но эти шаги не выразить в DFA.

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

Публикации