State Machines Battlefield-Naive vs STL vs Boost
04 Apr 2019
|
|
演讲主题是对比状态机各种实现上的效率,源代码2,项目文档1,ppt3见参考链接
简单说,SML在各种benchmark比较上没拖后腿,然后列举了各种实现上的优缺点
具体的比较图标还是看ppt3吧,一张一张截图太费劲了,这里主要把各种实现的优缺点列一下,所有代码实现见参考链接4
if/else状态机
- (+) 内联
- (+) 没有堆内存分配
- (~) 内存占用小
- (-) 不可复用 if-else hell
switch/enum状态机
- (+) 内联
- (+) 没有堆内存分配
- (~) 内存占用小
- (-) 不可复用
继承 状态模式
- (+) 容易复用,扩展(重写接口即可)
- (~) 内存占用稍高
- (-) 堆内存分配
- (-) 无法内联,效率不行
std::variant + std::visit
- (+) 内存占用低,高效
- (+) 集成了std::expected
- (~) 内联 (clang)
- (-) 无法复用,类似switch/enum,类型加强了
coroutines + loop
- (+) c++ 特性,组织好
- (+) 很容易切换成同步异步的版本
- (~) 学习曲线高,和上面的思路不同
- (~) 堆内存 (heap elision / devirtualization)
- (~) 隐式状态(需要提供函数默认行为)
- (-) 所有事件都是相同的类型
- (-) 奇怪的死循环写法
coroutines + goto
- (+) 没有死循环
- (+) 显式状态
- (-) goto
coroutines + functions + variant
把死循环放到函数里,co_return 函数
- (+) 容易维护,添加新事件状态
- (+) 类型安全事件
boost statechart
- (+) UML
- (~) 学习曲线高,类似状态模式,写接口
- (-) 动态类型
- (-) 动态派发
- (-) 高内存使用
boost msm
- (+) UML 声明模式
- (+) 分派实现,jump table
- (+) 内存使用很小
- (~) 学习曲线高
- (~) DSL
- (-) 宏
- (-) 编译时间漫长
- (-) 错误信息恐怖
boost sml
现代,可指定多种分派策略 jump table / nested switch / fold expressions
-
(+) UML 声明模式
-
(+) 编译期定制
-
(+) 内联,O1分派
-
(+) 编译速度快
-
(+) 占用内存小
-
(~) DSL
-
(~) 学习曲线高
reference
- https://boost-experimental.github.io/sml/
- https://github.com/boost-experimental/sml
- 演讲ppt
- ppt中的demo实现 https://github.com/boost-experimental/sml/tree/master/benchmark/connection
或者到博客上提issue 我能收到邮件提醒。