Очевидно, boost содержит две отдельные библиотеки для конечных автоматов: Statechart и Meta State Machine (MSM). Слоганы дают очень похожие описания:
- Boost.Statechart - Конечные автоматы произвольной сложности могут быть реализованы в легко читаемом и поддерживаемом коде C ++.
- Meta State Machine - высокопроизводительная библиотека для выразительных конечных автоматов UML2.
Знаете ли вы, в чем заключаются основные различия и что нужно учитывать при выборе между ними?
c++
boost
state-machine
boost-statechart
boost-msm
FireAphis
источник
источник
Ответы:
Поскольку, похоже, есть большой интерес, позвольте мне высказать свое (явно предвзятое) мнение, к которому следует относиться с недоверием:
Вы можете составить себе лучшее мнение, просмотрев комментарии, опубликованные во время обзора MSM. Эта тема много обсуждалась в списке разработчиков.
источник
Как уже упоминал Кристоф, одно из ключевых различий между двумя библиотеками - это производительность во время выполнения. В то время как MSM, вероятно, предлагает лучшее, что вы можете здесь получить, Statechart сознательно меняет память и циклы процессора на лучшую масштабируемость.
С Boost.Statechart вы можете распределить макет (то есть состояния, переходы) вашего конечного автомата по нескольким единицам перевода (файлам cpp) способами, которые вы не можете с MSM. Это позволяет сделать реализацию больших автоматов более удобной в обслуживании и получить гораздо более быструю компиляцию, чем при использовании MSM.
Независимо от того, будут ли накладные расходы на производительность Statechart по сравнению с MSM действительно значительными для вашего приложения, часто довольно легко ответить, если вы спросите себя, сколько событий ваше приложение должно будет обрабатывать в секунду.
Предполагая, что конечный автомат средней сложности реализован с помощью Boost.Statechart, вот несколько приблизительных цифр:
Что касается загрузки ЦП, если количество событий для обработки намного меньше этих чисел, накладные расходы Boost.Statechart по сравнению с MSM почти наверняка не будут заметны. Если число намного выше, вам определенно будет лучше с МСМ.
Более подробную информацию о компромиссах производительности / масштабируемости можно найти здесь: http://www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html
источник
При написании моей собственной реализации PPP я использовал диаграмму состояний по трем причинам: 1) диаграмма состояний проще и имеет более понятную документацию; 2) Мне очень не нравится UML :)
Документы по ускорению говорят, что MSM как минимум в 20 раз быстрее, но компилируется довольно медленно для больших FSM.
источник
Некоторое время назад я начал с Statechart и перешел на MSM, потому что его было проще использовать в сочетании с asio из одного потока. Мне не удалось связать Statechart и его возможности многопоточности с использованием asio - вероятно, это было своего рода непонимание Statechart новичком с моей стороны. Я обнаружил, что MSM проще использовать, поскольку он не решает проблему многопоточности.
источник
В ответ на позднее вступление Тима в обсуждение (которое также относится к одному из самых ранних комментариев Льва).
Как один из тех, кто выступал за разделение выхода из деструкторов в диаграмме состояний (аргумент, основанный на реальном варианте использования, о взаимодействии с реальным миром, то есть ввод-вывод), еще когда он был отправлен в Boost, я согласен, что могут возникнуть проблемы с помещением exit логика в деструкторах. Неудивительно, что Дэвид Абрахамс также привел убедительные аргументы относительно безопасности исключений. По этим причинам Statechart не требует, чтобы вы помещали логику в деструкторы, но позволяет вам это делать обычным советом.
Логика, которая должна запускаться только как часть перехода из состояния (а не разрушения объекта диаграммы состояний в целом), может (и должна, если есть также очистка ресурсов) быть выделена в отдельное действие exit ().
Для «тонкого» состояния без активного состояния (ресурсов), нужно выполнить только действия входа / выхода, вы можете выполнить эти действия в ctor и d'tor и убедиться, что конструктор и деструктор не бросают. Для них нет причин - нет состояния для выполнения RAII - нет ничего плохого в том, что обработка ошибок в этих местах вызывает соответствующие события. Возможно, вам все еще нужно подумать, хотите ли вы, чтобы действия выхода, которые изменяют внешнее состояние, выполнялись при уничтожении конечного автомата ... и помещали их в действие выхода, если вы не хотите, чтобы они происходили в этом случае ...
Диаграмма состояний моделирует активацию как создание экземпляра объекта, поэтому, если у вашего конструктора есть реальная работа / активация / создание экземпляра, и если он может дать сбой, так что состояние не может быть введено, Statechart поддерживает это, давая вам возможность сопоставить исключение с событие. Это обрабатывается способом, который обрабатывает иерархию состояний, ища внешнее состояние, которое обрабатывает событие исключения, аналогично тому, как стек будет раскручиваться для модели вызова на основе стека вызовов.
Все это хорошо задокументировано - я предлагаю вам прочитать документацию и попробовать. Я предлагаю вам использовать деструкторы для очистки «программных ресурсов» и действия выхода для выполнения «реальных действий выхода».
Стоит отметить, что распространение исключений представляет собой небольшую проблему во всех средах, управляемых событиями, а не только в диаграммах состояний. Лучше всего рассуждать о сбоях / ошибках и включать их в структуру диаграммы состояний, и если и только если вы не можете справиться с ними другим способом, прибегайте к сопоставлению исключений. По крайней мере, у меня это работает - ммммм ....
источник