可选的性能分析代码执行的高效设计

时间:2017-10-11 02:20:30

标签: c++ algorithm templates profiling traveling-salesman

某些背景信息:

我有一个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,它仍然比没有这个代码慢得多。

因此,我的问题如下:是否有一种设计可以让我实现相同的行为,但是当我不需要收集统计数据时,与没有这些代码相比,效率没有降低?

我能想到的每个模板解决方案似乎仍然涉及某种类似上面的运行时检查,因此更耗时。

非常感谢你的帮助!

PS:我是新来的,所以我欢迎建设性的反馈,让我的问题更加清晰。

1 个答案:

答案 0 :(得分:1)

将函数模板化为StatGatherer或具有内联无操作实现(并通过引用传递)的模拟。编译器将使用mock完全删除实例化中的伪调用。

另一种避免使用模拟方法但需要原始版本if(statGatherer && ...) statGatherer->...(...);的替代方法是模拟指针:让模板参数为StatGatherer*或伪指针类型:

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