4

Is it possible that instead of checking a bool (and thus branchning) in a function, it could be faster to evaluate the bool beforehand and just change a function pointer to the desired behaviour?

Consider:

#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();
}

Note: this is the same question as Pointer dereferencing overhead vs branching / conditional statements , only in a more abstract form. The question in this link was not answered satisfactory, in the sense that the core of the question (de-ref vs branch) was largely ignored.

Thomas B.
  • 691
  • 4
  • 15
  • Not sure, but i could imagine that branching in the `DoWork()` should be faster IF you could eliminate a function call altogether with it. If the Flag dosn't flip around in 50/50 state the branch predictor will (hopefully) find that and optimze – Taron Jan 17 '20 at 08:11
  • 2
    The answer to your question depends on so many factors. Have you tried implementing it and benchmarking the results? Have your benchmarks identified this area as a performance bottleneck in your code? – Alan Birtles Jan 17 '20 at 08:18
  • 2
    Note that `std::function` applies _type erasue_, which brings a lot of overhead as well. Branching may or may not be faster, this depends on many factors. Note that instead of `std::function`, you can use a _member-function pointer_, but then, your alternatives must be member functions. – Daniel Langr Jan 17 '20 at 08:39
  • Is it possible? Yes. Is it guaranteed with all approaches? No. Is any particular approach guaranteed to always be optimal, by whatever measure you choose? No. – Peter Jan 17 '20 at 08:42
  • 2
    Jump prediction versus branch prediction. I think currently branch prediction does better job. – Jarod42 Jan 17 '20 at 08:45
  • If you are looking for a faster code, just write simple instructions. otherwise you have to add to your code some extra functions and stuff that will make the code slower ! – Blood-HaZaRd Jan 17 '20 at 09:27
  • This is not a real life example, nor is it based on one. But should that problem ever arise, I want to know which tools I have at my disposal. Especially if it's not 50/50 for a simple bool, but a high™ number of possibilities. – Thomas B. Jan 17 '20 at 09:39

1 Answers1

0

Better to follow factory design pattern. Something like below:

#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();
}