【发布时间】:2013-06-05 19:58:20
【问题描述】:
我使用 boost msm 库创建了一个有限状态机。事件及其转换在编译时以声明方式定义。然而,在运行时,需要一些代码根据输入数据选择正确的事件。目前代码如下所示:
enum : unsigned {
fin = (1 << 0),
syn = (1 << 1),
ack = (1 << 4)
// etc...
};
// events
struct receive_syn {};
struct receive_syn_ack {};
struct receive_fin {};
struct receive_fin_ack {};
struct receive_ack {};
// etc..
void receive(const Segment& segment)
{
switch (segment.getFlags())
{
case syn|ack: state_machine.process_event(receive_syn_ack{}); break;
case syn: state_machine.process_event(receive_syn{}); break;
case fin|ack: state_machine.process_event(receive_fin_ack{}); break;
case fin: state_machine.process_event(receive_fin{}); break;
case ack: state_machine.process_event(receive_ack{}); break;
// etc..
}
}
它有效,而且速度可能很快。不过,我觉得这应该写成更声明的风格。
如何在不引入额外运行时开销的情况下以更高级别的编程风格实现这一点?
供参考,这里是boost::msm example。
【问题讨论】:
-
我推荐一个函数指针的哈希表,这是我在这种情况下通常做的第一件事。哈希表的查找速度为 O(1),因此它的性能甚至比您当前的实现还要好。
-
编译器可能会将开关转换为查找表;在这种情况下,当前实现的性能不会比哈希表差。
-
我怀疑哈希值的计算加上函数指针的调用会比开关更昂贵。另外
O(1)不一定比O(n)快。 Big-O 是增长率的特征。在我的情况下,N 相对较小( -
如果你将枚举的值设为一个连续的整数序列,那么枚举可以用作表的索引。
-
receive_syn_ack等是空类型吗?
标签: c++