7

In my jpg decoder I have a loop with an if statement that will always be true or always be false depending on the image. I could make two separate functions to avoid the if statement but I was wondering out of curiosity what the effect on efficiency would be using a function pointer instead of the if statement. It will point to the inline function if true or point to an empty inline function if false.

class jpg{
  private:
    // emtpy function
    void inline nothing();
    // real function
    void inline function();
    // pointer to inline function
    void (jpg::*functionptr)() = nullptr;
}

jpg::nothing(){}

main(){

  functionptr = &jpg::nothing;
  if(trueorfalse){
    functionptr = &jpg::function;
  }

  while(kazillion){

    (this->*functionptr)();

    dootherstuff();

  }
}

Could this be faster than an if statement? My guess is no, because the inline will be useless since the compiler won't know which function to inline at compile time and the function pointer address resolve is slower than an if statement.

I have profiled my program and while I expected a noticeable difference one way or the other when I ran my program... I did not experience a noticeable difference. So I'm just wondering out of curiosity.

deanresin
  • 1,466
  • 2
  • 16
  • 31
  • 2
    Do you know about [branch prediction](https://en.wikipedia.org/wiki/Branch_predictor)? Is this coming into it for you? – Mike Apr 07 '14 at 03:59
  • I have realized that I should just really avoid the if statement altogether since it will always be true or always be false. – deanresin Apr 07 '14 at 05:07
  • @deanresin you should work on your naming convention: `trueorfalse`, `dootherstuff`. – Mahdi Apr 07 '14 at 08:24
  • 2
    @deanresin I'm not arguing with avoiding the `if` statement or putting the loop inside it, as mbonneau suggests; I'm just suggesting that branch prediction could explain why you didn't see much difference. (Well, that and potentially the fact that the `if` statement and pointer resolution are far more lightweight than your function bodies as profiled.) – Mike Apr 07 '14 at 13:08
  • 1
    @Mike I think you are right about the weight of my if statement/pointer resolution vs. the rest of the function body. Also.. and to paraphrase you.. I am not noticing a difference possibly because the CPU's branch prediction is mitigating any potential slow downs. – deanresin Apr 07 '14 at 19:07
  • @Mahdi it is half pseudo code – deanresin Apr 07 '14 at 19:07

2 Answers2

9

It is very likely that the if statement would be faster than invoking a function, as the if will just be a short jump vs the overhead of a function call.

This has been discussed here: Which one is faster ? Function call or Conditional if Statement?

The "inline" keyword is just a hint to the compiler to tell it to try to put the instructions inline when assembling it. If you use a function pointer to an inline, the inline optimization cannot be used anyway:

Read: Do inline functions have addresses?

If you feel that the if statement is slowing it too much, you could eliminate it altogether by using separate while statements:

if (trueorfalse) {
    while (kazillion) {
        trueFunction();
        dootherstuff();
    }
} else {
    while (kazillion) {
        dootherstuff();
    }
}
Community
  • 1
  • 1
mbonneau
  • 627
  • 3
  • 8
1

Caution 1: I am not really answering the above question, on purpose. If one wants to know what it faster between an if statement and a function call via a pointer in the above example, then mbonneau gives a very good answer.

Caution 2: The following is pseudo-code.

Besides curiosity, I truly think one should not ask himself what is faster between an if statement and a function call to optimize his code. The gain would certainly be very small, and the resulting code might be twisted in such a way it could impact readability AND maintenance.

For my research, I do care about performance, this is a fundamental notion I have to stick with. But I do more care about code maintenance, and if I have to choose between a good structure and a slight optimization, I definitely choose the good structure. Then, if it was me, I would write the above code as follows (avoiding if statements), using composition through a Strategy Pattern.

class MyStrategy {
  public:
    virtual void MyFunction( Stuff& ) = 0;
};

class StrategyOne : public MyStrategy {
  public:
    void MyFunction( Stuff& ); // do something
};

class StrategyTwo : public MyStrategy {
  public:
    void MyFunction( Stuff &stuff ) { } // do nothing, and if you 
                                        // change your mind it could
                                        // do something later.
};

class jpg{
  public:
    jpg( MyStrategy& strat) : strat(strat) { }
    void func( Stuff &stuff ) { return strat.MyFunction( stuff ); }
  private:
    ...
    MyStrategy strat;
}

main(){

  jpg a( new StrategyOne );
  jpg b( new StrategyTwo );
  vector<jpg> v { a, b };

  for( auto e : v )
  {
    e.func();

    dootherstuff();

  }
}
Florian Richoux
  • 1,543
  • 1
  • 14
  • 28
  • I was under the impression that [virtual methods are essentially the same as function pointers](http://programmers.stackexchange.com/a/191641) in this sense; both need to be resolved, and the resolution can slow things down. Is that not true? – Mike Apr 07 '14 at 22:39
  • @Mike Yes, this is true. Actually I am not really answering the question asked here, and I should specify this in my answer (will do it right now). My point is, even if ones really care about performances (like I do), I am not sure looking for what is faster between an if statement and a function pointer is the right question when one is optimizing a code. Which is not the case here, since deanresin clearly stated it was for satisfying his/her curiosity. – Florian Richoux Apr 08 '14 at 00:34