【问题标题】:function pointer vs conditional branching函数指针与条件分支
【发布时间】:2020-05-04 02:26:01
【问题描述】:

是否有可能不是检查函数中的布尔值(从而分支),而是预先评估布尔值并将函数指针更改为所需的行为可能会更快?

考虑:

#include <iostream>

class A
{
public:
    A()
    {
        workTrue = [] () { std::cout << "True" << std::endl; };
        workFalse = [] () { std::cout << "False" << std::endl; };
        SetArgs(false);
    }

    void SetArgs(bool _b)
    {
        b = _b;
        work = b ? &workTrue : &workFalse;
    }

    void DoWork()
    {
        (*work)();
        // b ? workTrue() : workFalse();
    }

private:
    std::function<void()> workTrue;
    std::function<void()> workFalse;
    std::function<void()>* work;
    bool b;
};


int main()
{
    A a;
    a.DoWork();
}

注意:这与Pointer dereferencing overhead vs branching / conditional statements 是同一个问题,只是形式更抽象。此链接中的问题没有得到令人满意的回答,因为问题的核心(de-ref vs branch)在很大程度上被忽略了。

【问题讨论】:

  • 不确定,但我可以想象,如果您可以完全消除函数调用,DoWork() 中的分支应该会更快。如果标志没有在 50/50 状态下翻转,分支预测器将(希望)找到并优化
  • 您的问题的答案取决于很多因素。您是否尝试过实施它并对结果进行基准测试?您的基准测试是否将此区域确定为代码中的性能瓶颈?
  • 请注意,std::function 应用了 type erasue,这也会带来很多开销。分支可能会或可能不会更快,这取决于许多因素。请注意,除了std::function,您可以使用成员函数指针,但是,您的替代方案必须是成员函数。
  • 有可能吗?是的。所有方法都能保证吗?否。无论您选择何种衡量标准,是否有任何特定方法可以保证始终是最佳的?没有。
  • 跳转预测与分支预测。我认为目前分支预测做得更好。

标签: c++ conditional-statements branch


【解决方案1】:

最好遵循工厂设计模式。如下所示:

#include <iostream>

class WorkFactory
{
 public:
    WorkFactory()
    {
    }
    virtual void Work() = 0;
};

class WorkFalse : public WorkFactory
{
 public:
    WorkFalse()
    {
    }
    void Work() final
    {
        std::cout << "False" << std::endl;
    }
};

class WorkTrue : public WorkFactory
{
 public:
    WorkTrue()
    {
    }
    void Work() final
    {
        std::cout << "True" << std::endl;
    }
};

int main()
{
    WorkFactory* w;
    bool var = false;
    if (var)
    {
        w = new WorkTrue();
    }
    else
    {
        w = new WorkFalse();
    }

    w->Work();
}

【讨论】:

    猜你喜欢
    • 2011-11-20
    • 2014-12-02
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 2022-11-12
    • 2017-12-28
    • 2019-01-27
    相关资源
    最近更新 更多