Boost Statechart vs. Meta State Machine

34,777

Solution 1

As there seems to be much interest, please allow me to give my (obviously biased) opinion, which should therefore be taken with a grain of salt:

  • MSM is much faster
  • MSM requires no RTTI or anything virtual
  • MSM has a more complete UML2 support (for example internal transitions, UML-conform orthogonal regions)
  • MSM offers a descriptive language (actually several). For example, using the eUML front-end, a transition can be described as Source + Event [Guard] / Action == Target
  • MSM will make your compiler suffer for bigger state machines, so you will need a pretty recent compiler (g++ >= 4.x, VC >= 9)

You can make yourself a better opinion by looking for comments posted during the review of MSM. This subject was much discussed on the developer list.

Solution 2

As Christophe has already mentioned, one of the key differences between the two libraries is runtime performance. While MSM probably offers the best you can get here, Statechart consciously trades memory and processor cycles towards better scalability.

With Boost.Statechart you can spread the layout (i.e. states, transitions) of your state machine over multiple translation units (cpp files) in ways you can't with MSM. This allows you to make the implementation of large FSMs more maintainable and get much faster compilation than with MSM.

Whether or not the performance overhead of Statechart compared to MSM will actually be significant for your application is often quite easy to answer when you ask yourself how many events your app will have to process per second.

Assuming a moderately complex FSM implemented with Boost.Statechart, here are a few ballpark numbers:

  • Most current PC hardware will easily cope with >100'000 events per second
  • Even very resource-constrained hardware will be able to process a few hundred events per second.

Regarding CPU load, if the number of events to process is much lower than these numbers, Boost.Statechart overhead compared to MSM will almost certainly not be noticeable. If the number is much higher, you're definitely better off with MSM.

More in-depth information on the performance/scalability tradeoffs can be found here: http://www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html

Solution 3

While coding my own PPP implementation I used Statechart for three reasons: 1) Statechart is simpler and has clearer documentation; 2) I really dislike UML :)

Boost docs say MSM is at least 20 times faster, but compiles pretty slow for large FSM.

Solution 4

Some time ago I began with Statechart and moved to MSM because it was easier to use in conjunction with asio from a single thread. I did not manage to mesh Statechart and its multithreading capabilities with my use of asio - it was likely some sort of newbie incomprehension of Statechart on my part. I found that MSM was easier to use as it did not address multithreading.

Solution 5

In answer to Tim's late entry to the discussion (which also addresses one of the very early comments from Lev).

As one of those who argued for exit separation from destructors in statechart (argument based on a real use case, about interaction with the real world i.e. I/O) way back when it was submitted to Boost I agree there can be issues in putting exit logic in destructors. David Abrahams unsurprisingly made persuasive arguments regarding exception safety as well. For those reasons Statechart doesn't require you to put logic in destructors - but it allows you to - with the usual advice.

Logic that should only ever run as part of a transition out of a state (not destruction of the statechart object as a whole) can (and should if there is also resource cleanup to do) be separated into a separate exit() action.

For a "thin" state with no active state (resources), just entry/exit actions to perform, you can perform those actions in ctor and d'tor and make sure the constructor and destructor don't throw. There is no reason for them to - there is no state to perform RAII on - there is no evil in having the error handling in these places raise appropriate events. You may still need to consider whether you want exit actions that alter external state to run on state machine destruction though... and put them in exit action if you don't want them to occur in this case...

Statechart models activation as instantiation of an object, so if your constructor has real work/activation/instantiation to do and if it is able to fail such that the state cannot be entered Statechart supports that by giving you the ability to map an exception to an event. This is handled in a way that works up the state hierarchy looking for an outer state that handles the exception event, analogous to the way the stack would have unwound for a call stack based invocation model.

This is all well documented - I suggest you read the docs and try it. I suggest that you use destructors to clean up "software resources" and exit actions to perform "real-world exit actions".

It is worth noting note that exception propagation is a bit of a problem in all event driven environments, not just statecharts. It is best to reason about and include faults/errors in your statechart design and if and only if you can't handle them another way resort to exception mapping. At least that works for me - ymmmv....

Share:
34,777

Related videos on Youtube

FireAphis
Author by

FireAphis

#SOreadytohelp

Updated on November 04, 2020

Comments

  • FireAphis
    FireAphis over 3 years

    Apparently boost contains two separate libraries for state machines: Statechart and Meta State Machine (MSM). The taglines give very similar descriptions:

    • Boost.Statechart - Arbitrarily complex finite state machines can be implemented in easily readable and maintainable C++ code.
    • Meta State Machine - A very high-performance library for expressive UML2 finite state machines.

    Do you know what are the key differences and what are considerations in choosing between the two?

    • Ankit Roy
      Ankit Roy over 13 years
      Hehe, another case of lots of interest but no-one knows the answer... :)
    • FireAphis
      FireAphis over 13 years
      :D This question is the pinnacle of my SO experience! Getting answers from both developers... can it get any better?! Many thanks to Christophe and Andreas.
    • Offirmo
      Offirmo over 12 years
      Excellent question and you managed to get the answers of the two competing developpers !
    • Lev
      Lev over 10 years
      Statechart makes you put functionality into constructors and destructors. That's an anti-pattern, especially with destructors.
    • Tim Crews
      Tim Crews over 8 years
      In Statechart, exit actions can be put in a separate exit() handler that is called before destruction. I think this provision mitigates the main problem with the anti-pattern that Lev mentions.
    • kebs
      kebs almost 5 years
      As third choice, you might also consider this C++11 FSM library: github.com/skramm/spaghetti
  • Jon Trauntvein
    Jon Trauntvein over 13 years
    Whilst I agree that much of UML is the emperors new clothes, state charts are the one thing that actually has value in UML.
  • blaze
    blaze over 13 years
    Definitely, but I learned statecharts from discrete math, not software engineering. This leaves a mark :)
  • FireAphis
    FireAphis over 13 years
    Thank you very much. It's a delight to hear the opinion of the developer itself! Now we only need the response of Andreas Huber :)
  • Admin
    Admin over 13 years
    Minor nit-pick: In release mode, the use of C++ RTTI (dynamic_cast, typeid) is strictly optional with Boost.Statechart.
  • Christophe Henry
    Christophe Henry over 13 years
    Hi Andreas, about the spreading of layout, there have been some improvements. You can now compile submachines on different cores. It is not perfect but a noticeable improvement. See svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/…
  • Admin
    Admin over 12 years
    Most statechart types do not address threading either. With regards to multithreading, you should be able to use boost::statechart::state_machine just like the MSM counterpart. boost::statechart::asynchronous_state_machine and associated types are a strictly optional part of the statechart library.
  • Tim Crews
    Tim Crews over 8 years
    Thank you, I see that all of my concerns are sufficiently addressed in the "Exception handling" part of the Boost::statechart tutorial. In that case, I think that Lev's (misleading) comment can be addressed simply by pointing to the "two-stage exit" section of that tutorial. I would consider deleting my answer, except that your own answer adds valuable information to this topic.
  • neonxc
    neonxc over 3 years
    @ChristopheHenry, the link requires a username and password. Any chance of public access? Thank you.
  • a.peganz
    a.peganz about 3 years
    @neonxc Here is a link to the boost documentation built from the source the SVN link points to: boost.org/doc/libs/1_75_0/libs/msm/doc/HTML/…
  • rahul.deshmukhpatil
    rahul.deshmukhpatil about 2 years
    Also, spreading layout in different files: can we use ".IPP" or implementation files (used for the C++ templates implementation) and include them in the single source file? This approach may only spread the layout in diff files, compilation unit will be still single source file.