一些上下文:
我有一个c++方法,它执行一些密集的计算(关于车辆路径问题变化的一些分支定界算法)。因此,在本规范中,效率是最重要的。
当我测试不同的技巧以达到最佳速度时,我最终实现了一个类StatGatherer,该类在算法的给定运行期间收集信息(即:找到了多少可行路径,多少有界,多少不可行…)代码如下所示:

void doStuff(const shared_ptr<StatGatherer>& statGatherer = NULL)
{
    //do some stuff
    ...

    if (statGatherer != NULL && some unfeasibility condition)
        statGatherer->countOneFeasiblePath();

    //do more stuff
    ...

    if (statGatherer != NULL && some bounding criterium on the current path)
        statGatherer->countOneBoundedPath();

    //do more stuff
    ...

    if (statGatherer != NULL && a whole path has been found)
        statGatherer->countOneBoundedPath();
    ...

    //...more information gathering triggered by certain events
}

这工作得很好,但具有讽刺意味的是,这种涉及statGatherer的“分析”代码的出现大大降低了算法的速度,因为上面的伪代码执行了数千万次。即使没有提供statGatherer并且默认为null,它仍然比完全没有此代码慢很多。
因此,我的问题是:是否有一种设计可以让我实现相同的行为,但是当我不需要收集统计数据时,与完全没有这段代码相比,不会损失效率?
我能想到的每一个模板解决方案似乎仍然涉及到像上面这样的运行时检查,所以仍然比较耗时。
非常感谢你的帮助!
注:我是新来的,所以我欢迎建设性的反馈,使我的问题更清楚。

最佳答案

StatGatherer类型或具有inline-do-nothing实现的mock上创建函数模板(并通过引用传递)编译器将使用mock完全删除实例化中的伪调用。
另一种方法是模拟指针:模板参数要么是if(statGatherer && ...) statGatherer->...(...);要么是伪指针类型:

template<class T>
struct dummy_ptr {
  operator T*() const {return nullptr;}
  T* operator->() const {return nullptr;}
};

09-27 11:25