SlideShare a Scribd company logo
Компилируемые в реальном
времени DSL для С++
Юрий Ефимочев
О себе
Архитектор в LogicNow
Специализация: высоконагруженные
отказоустойчивые системы на C++
Бэкап-решение
Что такое DSL?
Domain-specific language - это язык программирования с
ограниченными возможностями, ориентированный на конкретную
предметную область.
Достоинства и недостатки DSL
Достоинства:
• управление сложностью
• скорость разработки
• комуникация с экспертами
• альтернативные парадигмы
• динамическое выполнение
Недостатки:
• порог вхождения
• эволюция в язык общего назначения
• разработка и поддержка
Классификация DSL
• Внутренние
• Внешние
• Визуальные
• Интерпретируемые
• Компилируемые
Пример: тестирование
Given(
Node("a")
(Node("b")
(Node("c"))
(Node("d")))
(Node("e")
(Node("f"))
(Node("g"))));
When().Filter("%f%");
Expect(
Node("a")
(Node("e")
(Node("f"))));
a
b
c d
e
f g
a
e
f
Архитектура DSL
Программа
на
DSL
Семантическая
модель
Целевой
код
Опционально
Постановка задачи
Дано:
~ 100 000 объектов
~ 500 параметров у объекта
Требуется:
получение актуальной статистики по произвольной
выборке объектов
Примеры запросов
Count(true)
Count(LastSession.Timestamp < 2.days().ago())
Count(Version like ‘15.12.%’)
Count(LastSession.Status == SessionStatus::Failed)
Average(LastSession.Duration)
Sum(UsedStorage)
Архитектура решения
Expression AST Result
Data
Синтаксический анализ
Инструментарий:
• flex & bison
• antlr
• boost::spirit
Синтаксический анализ
%start Start;
AtomicExpression:
IntegerNumber { $$.Value = m_builder.CreateInteger($1.Name); } |
Identifier { $$.Value = m_builder.CreateVariable($1.Name) };
AddSubExpression:
AtomicExpression |
AddSubExpression Plus AddSubExpression { m_builder.CreateAddNode(...);
} |
AddSubExpression Minus AddSubExpression { m_builder.CreateSubNode(...);
};
Start:
AddSubExpression { result.AstTree.reset($1.Value); };
AST
Count(time > 2.days().ago()) Count
time ago
days
2
>
2.days().ago() = now - 2.days()
2.days() = 2 * 86400
AST
Count(time > 2.days().ago()) Count
time -
*
86400
>
now
2.days().ago() = now - 2.days()
2.days() = 2 * 86400
2
Реализация объектов AST
class IntegerNode : public IAstNode
{
public:
IntegerNode(int const value) :
m_value(value)
{
}
private:
virtual Variant Compile(IDataProvider& /*dataProvider*/) const
{
return Variant(m_value);
}
int const m_value;
};
Реализация объектов AST
class VariableNode : public IAstNode
{
public:
VariableNode(std::string const& name) :
m_name(name)
{
}
private:
virtual Variant Compile(IDataProvider& dataProvider) const
{
return Variant(dataProvider.GetVariableValue(m_name));
}
private:
std::string const m_name;
};
Реализация объектов AST
class AddNode : public IAstNode
{
public:
AddNode(IAstNodePtr left, IAstNodePtr right) :
m_left(std::move(left)),
m_right(std::move(right))
{
}
private:
virtual Variant Compile(IDataProvider& dataProvider) const
{
return m_left->Compile(dataProvider) + m_right->Compile(dataProvider);
}
private:
IAstNodePtr m_left;
IAstNodePtr m_right;
};
AST
Count(time > 2.days().ago()) Count
time -
*
86400
>
now
2.days().ago() = now - 2.days()
2.days() = 2 * 86400
2
Архитектура LLVM
Что такое LLVM IR?
Особенности:
• обобщенная система команд
• функции
• типы данных
• простые типы
• указатели
• массивы
• статическая типизация
• SSA(static single assignment) нотация
LLVM IR
bool MoveNext();
int GetValue();
int main()
{
int sum = 0;
while (MoveNext())
{
sum += GetValue();
}
return sum;
}
1 declare i1 @move_next()
2 declare i64 @get_value()
3
4 define i64 @main()
5 {
6 entry:
7 br label %loop_condition
8
9 loop_condition:
10 %1 = phi i64 [ 0, %entry ], [ %4, %loop_body ]
11 %2 = call i1 @move_next()
12 br i1 %2, label %loop_body, label %loop_exit
13
14 loop_body:
15 %3 = call i64 @get_value()
16 %4 = add i64 %3, %1
17 br label %loop_condition
18
19 loop_exit:
20 ret i64 %1
21 }
Архитектура решения
Expression AST
LLVM
IR AST
Native
code
Data
descriptor
Data
provider
Result
Data
Реализация AST
class IntegerNode : public IAstNode
{
public:
IntegerNode(int const value) :
m_value(value)
{
}
private:
virtual CompiledNode Compile(IDataProvider& context) const
{
return CompiledNode(DataType::Integer, context.GetBuilder().getInt64(m_value));
}
int const m_value;
};
Реализация AST
class VariableNode : public IAstNode
{
public:
VariableNode(std::string const& name) :
m_name(name)
{
}
private:
virtual CompiledNode Compile(ICompilationContext& context) const
{
return context.GetVariable(m_name);
}
private:
std::string const m_name;
};
Реализация AST
class AddNode : public IAstNode
{
public:
AddNode(IAstNodePtr left, IAstNodePtr right) :
m_left(std::move(left)),
m_right(std::move(right))
{
}
private:
virtual CompiledNode Compile(ICompilationContext& context) const
{
CompiledNode left = m_left->Compile(context);
CompiledNode right = m_right->Compile(context);
DataType::Enum const effectiveType = GetEffectiveType(left, right);
return CompiledNode(effectiveType, context.GetBuilder().CreateAdd(left, right));
}
private:
IAstNodePtr m_left;
IAstNodePtr m_right;
};
Производительность
Interpreted 1734 мс
LLVM 31 мс
LLVM(precompiled) 28 мс
Native 21 мс
Count(x < 50 && x > 22 || x == 77), size = 1000000
Кодогенерация
Инструментарий:
• LLVM
• Lua
• Chrome V8
Производительность
Interpreted 1734 мс
Lua 309 мс
Lua(precompiled) 276 мс
LLVM 31 мс
LLVM(precompiled) 28 мс
Native 21 мс
Count(x < 50 && x > 22 || x == 77), size = 1000000
Итоги
Плюсы:
• простота
• скорость разработки
• Производительность
Минусы:
• размер бинарного файла (~ 15 Mb)
• реализация местами сложна
• нативный код
?

More Related Content

PPTX
C++ idioms
PPTX
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
PDF
Конкурентные ассоциативные контейнеры
PPTX
Евгений Зуев, С++ в России: Стандарт языка и его реализация
PPTX
Статический и динамический полиморфизм в C++, Дмитрий Леванов
PPTX
Статический и динамический полиморфизм в C++, Дмитрий Леванов
PDF
хитрости выведения типов
PDF
практические советы по улучшению качества кода
C++ idioms
Обобщенное программирование в C++ или как сделать свою жизнь проще через стра...
Конкурентные ассоциативные контейнеры
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
хитрости выведения типов
практические советы по улучшению качества кода

What's hot (20)

PDF
C++ Базовый. Занятие 04.
PDF
TMPA-2015: Lexical analysis of dynamically formed string expressions
PDF
C++ Базовый. Занятие 02.
PPT
паскаль. часть1
PDF
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...
PDF
Дизайн больших приложений в ФП
PDF
Павел Павлов - Scala для Java программистов (JavaDay Nsk 28.11.2013)
PPTX
Программирование на языке C Sharp (СИ решетка)
PDF
Making of external DSL for Django ORM - Павел Петлинский, Rambler&Co
PDF
Back to the future: Функциональное программирование вчера и сегодня
PPTX
Расширяем идею статического анализа от проверки кода до других процессов разр...
PDF
TMPA-2013 Anureyev: On the Road to Technology of Developing the Means of Dedu...
PPTX
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
PPTX
Cpp/cli types
PDF
Программирование на языке C Sharp (СИ решетка) ПРАКТИКУМ
PDF
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
ODP
C language. Introduction
PPT
паскаль
PDF
Инкапсуляция и полиморфизм в ruby
PPT
операции с числами
C++ Базовый. Занятие 04.
TMPA-2015: Lexical analysis of dynamically formed string expressions
C++ Базовый. Занятие 02.
паскаль. часть1
TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Ana...
Дизайн больших приложений в ФП
Павел Павлов - Scala для Java программистов (JavaDay Nsk 28.11.2013)
Программирование на языке C Sharp (СИ решетка)
Making of external DSL for Django ORM - Павел Петлинский, Rambler&Co
Back to the future: Функциональное программирование вчера и сегодня
Расширяем идею статического анализа от проверки кода до других процессов разр...
TMPA-2013 Anureyev: On the Road to Technology of Developing the Means of Dedu...
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
Cpp/cli types
Программирование на языке C Sharp (СИ решетка) ПРАКТИКУМ
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
C language. Introduction
паскаль
Инкапсуляция и полиморфизм в ruby
операции с числами
Ad

Similar to Dsl for c++ (20)

PDF
Как приручить дракона: введение в LLVM
PDF
Tech Talks @NSU: Как приручить дракона: введение в LLVM
PDF
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
PPTX
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
PPTX
Convert this: peculiarities of cross-platform mobile game development at Vizor
PDF
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
PPTX
Современный статический анализ кода: что умеет он, чего не умели линтеры
PPTX
Программирование: от сложного к простому
PDF
static - defcon russia 20
PPTX
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
PPTX
Всё о статическом анализе кода для Java программиста
PDF
Павел Павлов - Scala для профессионалов - Joker 2013
PDF
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
PDF
20130429 dynamic c_c++_program_analysis-alexey_samsonov
PDF
Formal verification of operating system kernels
PDF
Комфортная разработка мобильных проектов
PPTX
что пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studio
PPTX
Принципы работы статического анализатора кода PVS-Studio
PDF
Scala, SBT & Play! for Rapid Application Development
PPTX
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Технологии анализа бинарного кода приложений: требования, проблемы, инструменты
Convert this: peculiarities of cross-platform mobile game development at Vizor
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Современный статический анализ кода: что умеет он, чего не умели линтеры
Программирование: от сложного к простому
static - defcon russia 20
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Всё о статическом анализе кода для Java программиста
Павел Павлов - Scala для профессионалов - Joker 2013
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
20130429 dynamic c_c++_program_analysis-alexey_samsonov
Formal verification of operating system kernels
Комфортная разработка мобильных проектов
что пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studio
Принципы работы статического анализатора кода PVS-Studio
Scala, SBT & Play! for Rapid Application Development
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
Ad

More from corehard_by (20)

PPTX
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
PPTX
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
PDF
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
PPTX
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
PPTX
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
PPTX
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
PPTX
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
PPTX
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
PPTX
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
PPTX
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
PDF
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
PPTX
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
PPTX
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
PDF
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
PDF
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
PDF
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
PDF
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
PPTX
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
PDF
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
PDF
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019

Dsl for c++

Editor's Notes

  • #4: ограниченные возможности - простота ограниченный язык полезен только если ориентирован на конкретную предметную область, иначе смысла нет неполнота по тьюрингу примеры: regexp, sql, cmake, make области применения: тесты, конфигурация, администрирование, финансы
  • #5: сложность - основная проблема разработки ПО(новые языки, фреймворки, ide) плюсы управление сложностью - инкапсуляция, проблема + реализация скорость разработки - проще понять, меньше ошибок, легче поддерживать комуникация с экспертами - не писать, так читать изменение в процессе выполнения - динамически меняющиеся области(финансы) альтернативные парадигмы - императивные, декларативные, функциональные без необходимости использования по всему проекту, интерприт минусы
  • #6: внутренний - специфический способ использования языка общего назначения(подмножество возможностей, определенный стиль, работа с небольшим аспектом системы) отличае от API связь методов(метод имеет смысл в контексте другого) совместимость - сгенерить код на С и заюзать в контроллере(на этапе компиляции) компилируемые - генерация, доп шаг при компиляции, совместимость
  • #8: первый шаг - синтаксический анализ второй шаг - генерация(опционален) синтаксис - описывает корректные выражения, которые могут встерчаться в программе семантика - это смысл программы строго говоря семантическая модель не обязательна, но очень желательна семантическая модель отделяет синтаксически анализ от результирующей семантики менять синтаксис независимо от логики, синтаксический сахар, заменить внутренний dsl на внешний dsl - тонкий слой над семантической моделью роль dsl это инициализация семантической модели с семантической моделью можно работать и без dsl семантическая модель не обязательно AST
  • #9: коллекция иерархическая 150К это максимум
  • #10: 2 части: аггрегирующая функция и выражение выражение применяется к каждому объекту
  • #11: LLVM IR AST - оптимимизация
  • #12: flex&bison граматика LARL проверена временем 80-ые, но до сих пор развивается работает быстро, парсера маленький по размеру сложно дебажить, не всегда понятные ошибки код который генерится не идеален(сырые указатели, union) antlr граматика LL antlrworks среда для разработки(дебаг, автрозрешение конфликтов, аст) ограниченная поддержка C++(4-ая версия не поддерживает, 3-яя поддерживает но ограниченно(безполезно)) парсер более требователен к ресурсам(больше памяти) spirit прикольная идея, построен на с++ шаблонах header-only либа, не требует доп шагов при компиляции адские ошибки для реальных грамматик огромное время компилляции
  • #14: yзлы - операторы листья - операнды отстутствуют узлы и ребра тех синтаксических правил, которые не влияют на семантику программы(например скобки, группировка операндов задается струтурой дерева) синтаксис описывает корректные выражения семантика - смысл
  • #15: yзлы - операторы листья - операнды отстутствуют узлы и ребра тех синтаксических правил, которые не влияют на семантику программы(например скобки, группировка операндов задается струтурой дерева) синтаксис описывает корректные выражения семантика - смысл
  • #19: yзлы - операторы листья - операнды отстутствуют узлы и ребра тех синтаксических правил, которые не влияют на семантику программы(например скобки, группировка операндов задается струтурой дерева) синтаксис описывает корректные выражения семантика - смысл
  • #21: разные языки, разные модели памяти, разные архитекруры, разные наборы инструкций ssa - функциональный стиль описания данных, императивный стиль описания операций нет переменных
  • #23: LLVM IR AST - оптимимизация
  • #30: нативный код - возможны крэши, мэмори ликик, ограниченные платформы и тп