встроенный доменный язык для генерации кода Java

Я работаю над программой, которая выполняет матричные и векторные операции на Java. Множественный вызов функций и создание объектов, которые происходят в моей текущей реализации, делают ее медленной и трудной для понимания.

Например, я хочу обновить положение механической точки путем интеграции скорости:

void update(Vector3 position, Vector3 speed, float dt){
   Vector3 displacement = new Vector3(speed);
   displacement.assignMul(dt);
   position.assignAdd(displacement);
}

Здесь API не естественно, и вдобавок мне нужно выделить сборку новой ссылки Vector3. Очевидно, я измерил значительное улучшение производительности в реальных случаях использования при встраивании вычислений таким образом:

void update(Vector3 position, Vector3 speed, float dt){
   position.x += speed.x * dt;
   position.y += speed.y * dt;
   position.z += speed.z * dt;
}

Есть ли какой-либо инструмент, который мог бы генерировать этот код из языка, специфичного для предметной области, по запросу? Синтаксис типа Cog был бы хорош. (Cog — это инструмент генерации кода от Неда Бэтчелдера)

void update(Vector3 position, Vector3 speed, float dt){
   // [[[DSL position += speed * dt ]]] 
   position.x += speed.x * dt;//Generated Code
   position.y += speed.y * dt;//Generated Code
   position.z += speed.z * dt;//Generated Code
   // [[[END]]]
}

person Pierre    schedule 28.04.2011    source источник
comment
Зачем усложнять простую операцию, такую ​​как матричная/векторная математика, генерацией кода? Какие цели вы стремитесь достичь? Производительность и читабельность? Последовательность? Простота?   -  person mellamokb    schedule 28.04.2011
comment
Я выбрал здесь тривиальный пример, реальные варианты использования не так просты. Первая цель — производительность программного обеспечения. Этого можно достичь, встроив себе каждую математическую операцию без какой-либо генерации кода. Вторая цель — повысить читаемость кода.   -  person Pierre    schedule 28.04.2011
comment
Как вы говорите, во втором примере кода вы получаете большую производительность. Однако это не просто инлайн, который вы выполняете. Я предполагаю, что то, что вы хотите, довольно сложно. Вы просматривали projectlombok.org? Возможно, вы могли бы создать AST для своего расчета в коде Java, который во время компиляции вы переписываете во второй пример.   -  person Alessandro Vermeulen    schedule 01.05.2011
comment
Я слишком поздно добавил ссылку на то, что я имею в виду, в свой предыдущий комментарий, но взгляните на: gist.github .com/950045   -  person Alessandro Vermeulen    schedule 01.05.2011
comment
@Alessandro, это хорошее предложение, оно позволяет при необходимости обойти процесс генерации кода и позволяет использовать инструменты анализа кода и инструменты рефакторинга.   -  person Pierre    schedule 02.05.2011
comment
@user282026 user282026, в дополнение к переписыванию кода в форму, используемую в сути, можно также поднять упомянутые функции до функций, которые создают выражение вместо выполнения вычисления. Затем вы можете оптимизировать выражение динамически или статически. Или вы могли бы сделать то же самое, но, взглянув на AST самого выражения, это может быть сложнее, так как вам придется учитывать весь язык Java, а не ваш специализированный Vector DSL.   -  person Alessandro Vermeulen    schedule 04.05.2011


Ответы (1)


Если вы настроены на генерацию кода, я настоятельно рекомендую книгу Шаблоны реализации языка» Теренса Парра. Он показывает, как можно создать абстрактное синтаксическое дерево (AST) на основе DSL, а затем использовать правила перезаписи для генерации кода.

Кроме того, он использует векторный DSL в качестве одного из своих примеров, в том числе показывая, как вы можете распределить постоянные умножения в синтаксическом дереве. например, Упрощение векторного DSL. Страница 141 шаблонов языковой реализации Теренса Парра

Соответствующим разделом для вас будет Глава 15, Сопоставление древовидных шаблонов.

Я согласен с некоторыми другими плакатами, что это может быть немного тяжело для ваших целей. Вы уверены, что не можете реализовать более удобный интерфейс, как показал @Alessandro Vermeulen в своем основном комментарии? Разница в скорости выглядит незначительной.

person I82Much    schedule 01.05.2011
comment
Строго говоря, это немного больше, чем встраивание, потому что все вычисления производятся из локальной переменной, и для хранения промежуточного результата больше не выделяется. Я собираюсь опубликовать там реальный пример с тестами. - person Pierre; 02.05.2011