没有虚函数的命令模式(C ++)

时间:2009-06-11 00:14:30

标签: c++ performance design-patterns templates virtual-functions

出于性能原因,我使用Curiously Reoccuring Template Pattern来避免虚函数。我有很多执行数百万次的小命令。我试图将其纳入命令模式。我想在队列中添加大量命令,然后迭代执行每个命令。每个命令使用CRTP来避免虚函数。我遇到的问题是Command模式通常使用指针向量来实现。但是当Command类被模板化时,很难传递通用的Command指针。我不是C ++专家,所以也许有一种显而易见的方法来存储模板化命令对象的向量?我一直试图使用类似的东西:

boost:ptr_vector commands;
AddCommand(Command* command) {
  commands.push_back(command);
}

问题是Command不是类型,因此Command* command会出现编译错误。我需要使用Command<CommandType>,但这不起作用,因为我需要队列来容纳不同类型的命令。

任何解决方案的想法?或者虚拟功能是我唯一的选择吗?

ADDED:命令对象是蒙特卡罗模拟算法的一部分。所以你可能有,Command是来自正态分布的随机数,其中正态分布的参数是类的一部分。所以命令模式非常合适。我按照特定的顺序对需要维护状态的函数进行了大量调用。

3 个答案:

答案 0 :(得分:11)

CRTP通过在编译时解析对象的运行时类型来实现其神奇功能,以便编译器可以内联函数调用。如果你有一个指向泛型类型的指针向量,编译器就无法确定具体的具体类型,也无法进行编译时解析。

从您问题中的信息来看,我认为虚拟功能是您的最佳选择。但是,虚函数并不那么慢。它们比内联功能慢,当然,但在很多情况下它们足够快!特别是如果您的过程受I / O时间限制而不是处理时间。

One of the answersthis question对此问题进行了更深入的讨论。总而言之,虚拟函数调用的开销可能以纳秒为单位进行测量。它比这更复杂,但关键是你不应该害怕虚函数,除非你的函数做的事情像一个单独的赋值一样微不足道。你说你的命令很小,所以也许就是这种情况。我尝试使用虚函数做一个快速原型,看看它是否能提供可接受的性能。

答案 1 :(得分:1)

除非您在编译期间构建命令队列,否则您想要的是不可能的。

答案 2 :(得分:1)

我无法判断您的命令队列是经常更改还是很少更改。

如果它很少变化,与执行频率相比,在我看来,这可能是代码生成的工作。

只需打印出一个程序即可完成所需的操作,编译和编辑。在运行中链接一个DLL,并加载它。这应该需要大约一秒钟。没有类,对象或调度。如果您单步执行它,您几乎看不到任何对您的答案没有实质性贡献的循环。