Повышение Statechart против Meta State Machine
Очевидно, boost содержит две отдельные библиотеки для конечных автоматов: Statechart и Meta State Machine (MSM). Слоганы дают очень похожие описания:
- Boost.Statechart - произвольно сложные конечные автоматы могут быть реализованы в легко читаемом и поддерживаемом коде C++.
- Meta State Machine - очень высокопроизводительная библиотека для выразительных конечных автоматов UML2.
Знаете ли вы, каковы ключевые различия и каковы соображения при выборе между ними?
5 ответов
Поскольку, кажется, есть большой интерес, пожалуйста, позвольте мне высказать свое (явно необъективное) мнение, которое, следовательно, следует воспринимать с недоверием:
- МСМ намного быстрее
- МСМ не требует никакого RTTI или чего-либо виртуального
- MSM имеет более полную поддержку UML2 (например, внутренние переходы, UML-соответствующие ортогональные области)
- МСМ предлагает описательный язык (на самом деле несколько). Например, используя интерфейс e UML, переход можно описать как Source + Event [Guard] / Action == Target
- MSM заставит ваш компилятор страдать от больших конечных автоматов, поэтому вам понадобится довольно свежий компилятор (g++ >= 4.x, VC >= 9)
Вы можете составить себе лучшее мнение, посмотрев комментарии, опубликованные в ходе обзора МСМ. Эта тема много обсуждалась в списке разработчиков.
Как уже упоминал Кристоф, одним из ключевых отличий между двумя библиотеками является производительность во время выполнения. В то время как MSM, вероятно, предлагает лучшее, что вы можете здесь получить, Statechart сознательно меняет циклы памяти и процессора в направлении лучшей масштабируемости.
С помощью Boost.Statechart вы можете распределить макет (то есть состояния, переходы) вашего конечного автомата по нескольким блокам перевода (файлам cpp) так, как это невозможно с MSM. Это позволяет сделать реализацию больших FSM более удобной для сопровождения и получить более быструю компиляцию, чем с MSM.
Вопрос о том, будут ли издержки производительности Statechart по сравнению с MSM на самом деле значимы для вашего приложения, часто довольно легко ответить, когда вы спрашиваете себя, сколько событий будет обрабатывать ваше приложение в секунду.
Предполагая, что FSM довольно сложный, реализованный с помощью Boost.Statechart, вот несколько приблизительных чисел:
- Самое современное оборудование ПК легко справится с>100'000 событий в секунду
- Даже оборудование с очень ограниченными ресурсами сможет обрабатывать несколько сотен событий в секунду.
Что касается загрузки ЦП, если число обрабатываемых событий намного ниже этих значений, накладные расходы Boost.Statechart по сравнению с MSM почти наверняка не будут заметны. Если число намного выше, вам определенно лучше с МСМ.
Более подробную информацию о компромиссах между производительностью и масштабируемостью можно найти здесь: http://www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html
При кодировании моей собственной реализации PPP я использовал Statechart по трем причинам: 1) Statechart проще и имеет более четкую документацию; 2) мне очень не нравится UML:)
В ускоренных документах говорится, что MSM работает как минимум в 20 раз быстрее, но для больших FSM компилируется довольно медленно
Некоторое время назад я начал с Statechart и перешел на MSM, потому что его было проще использовать вместе с asio из одного потока. Мне не удалось объединить Statechart и его возможности многопоточности с использованием asio - скорее всего, это было некое понимание новичка Statechart с моей стороны. Я обнаружил, что MSM проще в использовании, поскольку он не затрагивает многопоточность.
В ответ на поздний вступление Тима в дискуссию (в которой также рассматривается один из самых ранних комментариев Льва).
Как один из тех, кто выступал за разделение выхода от деструкторов в диаграмме состояний (аргумент, основанный на реальном случае использования, о взаимодействии с реальным миром, т. Е. Вводом / выводом), когда он был представлен в Boost, я согласен, что при размещении выхода могут возникнуть проблемы логика в деструкторах. Дэвид Абрахамс неудивительно выдвинул убедительные аргументы и в отношении безопасности исключений. По этим причинам Statechart не требует от вас помещать логику в деструкторы - но это позволяет вам - с обычным советом.
Логика, которая должна выполняться только как часть перехода из состояния (а не уничтожение объекта диаграммы состояний в целом), может (и должна, если необходимо выполнить очистку ресурса) быть разделена на отдельное действие exit ().
Для "тонкого" состояния без активного состояния (ресурсов), просто выполняемых действий входа / выхода, вы можете выполнить эти действия в ctor и d'tor и убедиться, что конструктор и деструктор не выдают. У них нет никаких причин - нет состояния для выполнения RAII - нет ничего плохого в том, что обработка ошибок в этих местах вызывает соответствующие события. Возможно, вам все еще нужно подумать, хотите ли вы, чтобы выходные действия, которые изменяют внешнее состояние, выполнялись при разрушении конечного автомата... и поместите их в выходное действие, если вы не хотите, чтобы они происходили в этом случае...
Диаграмма состояний моделирует активацию как создание объекта, поэтому, если у вашего конструктора есть реальная работа / активация / создание экземпляра, и если он может потерпеть неудачу, так что состояние не может быть введено, Statechart поддерживает это, предоставляя вам возможность сопоставить исключение с событие. Это обрабатывается способом, который обрабатывает иерархию состояний, ища внешнее состояние, которое обрабатывает событие исключения, аналогично тому, как стек должен был бы развернуться для модели вызовов на основе стека вызовов.
Все это хорошо документировано - я предлагаю вам прочитать документы и попробовать. Я предлагаю вам использовать деструкторы для очистки "программных ресурсов" и выходных действий для выполнения "реальных выходных действий".
Стоит отметить, что распространение исключений представляет собой небольшую проблему во всех управляемых событиями средах, а не только в диаграммах состояний. Лучше всего рассуждать и включать ошибки / ошибки в свой дизайн диаграммы состояний, и тогда и только тогда, когда вы не можете их обработать, другим способом прибегайте к отображению исключений. По крайней мере, это работает для меня - ymmmv....