Anscheinend enthält boost zwei separate Bibliotheken für Zustandsautomaten: Statechart und Meta State Machine (MSM). Die Slogans geben sehr ähnliche Beschreibungen:
- Boost.Statechart - Beliebig komplexe Finite-State-Maschinen können in leicht lesbarem und wartbarem C ++ - Code implementiert werden.
- Meta State Machine - Eine sehr leistungsstarke Bibliothek für ausdrucksstarke UML2-Finite-State-Maschinen.
Wissen Sie, was die Hauptunterschiede sind und welche Überlegungen bei der Wahl zwischen beiden zu berücksichtigen sind?
c++
boost
state-machine
boost-statechart
boost-msm
FireAphis
quelle
quelle
Antworten:
Da es großes Interesse zu geben scheint, erlauben Sie mir bitte, meine (offensichtlich voreingenommene) Meinung zu äußern, die daher mit einem Körnchen Salz aufgenommen werden sollte:
Sie können sich eine bessere Meinung bilden, indem Sie nach Kommentaren suchen, die während der Überprüfung von MSM veröffentlicht wurden. Dieses Thema wurde auf der Entwicklerliste viel diskutiert.
quelle
Wie Christophe bereits erwähnt hat, ist einer der Hauptunterschiede zwischen den beiden Bibliotheken die Laufzeitleistung. Während MSM wahrscheinlich das Beste bietet, was Sie hier bekommen können, handelt Statechart bewusst Speicher- und Prozessorzyklen, um eine bessere Skalierbarkeit zu erreichen.
Mit Boost.Statechart können Sie das Layout (dh Zustände, Übergänge) Ihrer Zustandsmaschine auf mehrere Übersetzungseinheiten (CPP-Dateien) verteilen, wie Sie es mit MSM nicht können. Auf diese Weise können Sie die Implementierung großer FSMs wartbarer machen und eine viel schnellere Kompilierung erzielen als mit MSM.
Ob der Leistungsaufwand von Statechart im Vergleich zu MSM für Ihre Anwendung tatsächlich erheblich ist oder nicht, lässt sich häufig leicht beantworten, wenn Sie sich fragen, wie viele Ereignisse Ihre App pro Sekunde verarbeiten muss.
Unter der Annahme eines mäßig komplexen FSM, der mit Boost.Statechart implementiert wurde, sind hier einige Ballpark-Nummern:
In Bezug auf die CPU-Auslastung wird der Overhead von Boost.Statechart im Vergleich zu MSM mit ziemlicher Sicherheit nicht spürbar sein, wenn die Anzahl der zu verarbeitenden Ereignisse viel geringer als diese Anzahl ist. Wenn die Zahl viel höher ist, sind Sie mit MSM definitiv besser dran.
Ausführlichere Informationen zu den Kompromissen zwischen Leistung und Skalierbarkeit finden Sie hier: http://www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html
quelle
Beim Codieren meiner eigenen PPP-Implementierung habe ich Statechart aus drei Gründen verwendet: 1) Statechart ist einfacher und hat eine klarere Dokumentation; 2) Ich mag UML wirklich nicht :)
Laut Boost-Dokumenten ist MSM mindestens 20-mal schneller, kompiliert jedoch für große FSM ziemlich langsam.
quelle
Vor einiger Zeit habe ich mit Statechart begonnen und bin zu MSM gewechselt, weil es einfacher war, in Verbindung mit asio von einem einzigen Thread aus zu verwenden. Ich habe es nicht geschafft, Statechart und seine Multithreading-Funktionen mit meiner Verwendung von asio zu verknüpfen - es war wahrscheinlich eine Art Neuling, das Statechart meinerseits nicht verstanden hat. Ich fand, dass MSM einfacher zu verwenden war, da es sich nicht mit Multithreading befasste.
quelle
Als Antwort auf Tims späten Eintritt in die Diskussion (der auch einen der sehr frühen Kommentare von Lev anspricht).
Als einer derjenigen, die sich vor langer Zeit bei der Übermittlung an Boost für die Trennung von Destruktoren im Statechart (Argument basierend auf einem realen Anwendungsfall, über die Interaktion mit der realen Welt, dh E / A) ausgesprochen haben, stimme ich zu, dass es Probleme geben kann, den Exit zu setzen Logik in Destruktoren. Es überrascht nicht, dass David Abrahams auch in Bezug auf die Ausnahmesicherheit überzeugende Argumente vorbrachte. Aus diesen Gründen verlangt Statechart nicht, dass Sie Logik in Destruktoren einfügen - aber es erlaubt Ihnen - mit den üblichen Ratschlägen.
Logik, die immer nur als Teil eines Übergangs aus einem Zustand ausgeführt werden sollte (nicht Zerstörung des gesamten Zustandsdiagrammobjekts), kann (und sollte, wenn auch eine Ressourcenbereinigung durchgeführt werden muss) in eine separate exit () -Aktion unterteilt werden.
Für einen "dünnen" Zustand ohne aktiven Zustand (Ressourcen), nur Ein- / Ausstiegsaktionen, können Sie diese Aktionen in ctor und d'tor ausführen und sicherstellen, dass der Konstruktor und der Destruktor nicht werfen. Es gibt keinen Grund für sie - es gibt keinen Zustand, an dem RAII durchgeführt werden kann - es ist nicht böse, wenn die Fehlerbehandlung an diesen Orten geeignete Ereignisse auslöst. Möglicherweise müssen Sie noch überlegen, ob Exit-Aktionen, die den externen Status ändern, bei Zerstörung der Zustandsmaschine ausgeführt werden sollen ... und sie in die Exit-Aktion setzen, wenn Sie in diesem Fall nicht möchten, dass sie ausgeführt werden ...
Statechart modelliert die Aktivierung als Instanziierung eines Objekts. Wenn Ihr Konstruktor also echte Arbeit / Aktivierung / Instanziierung zu erledigen hat und wenn dies fehlschlagen kann, sodass der Status nicht eingegeben werden kann, unterstützt Statechart dies, indem Sie eine Ausnahme einem zuordnen können Veranstaltung. Dies wird so gehandhabt, dass die Statushierarchie nach einem äußeren Zustand sucht, der das Ausnahmeereignis behandelt, analog zu der Art und Weise, wie der Stapel für ein auf einem Aufrufstapel basierendes Aufrufmodell abgewickelt worden wäre.
Dies ist alles gut dokumentiert - ich schlage vor, Sie lesen die Dokumente und versuchen es. Ich schlage vor, dass Sie Destruktoren verwenden, um "Softwareressourcen" zu bereinigen und Aktionen zu beenden, um "reale Exit-Aktionen" auszuführen.
Es ist anzumerken, dass die Weitergabe von Ausnahmen in allen ereignisgesteuerten Umgebungen ein Problem darstellt, nicht nur in Zustandsdiagrammen. Es ist am besten, Fehler zu begründen und in Ihr Statechart-Design aufzunehmen, und wenn und nur wenn Sie sie nicht auf andere Weise behandeln können, greifen Sie auf die Ausnahmezuordnung zurück. Zumindest funktioniert das bei mir - ymmmv ....
quelle