内联函数指针,以避免if语句

时间:2014-04-07 03:24:11

标签: c++ optimization function-pointers inline

在我的jpg解码器中,我有一个带有if语句的循环,它将始终为true或始终为false,具体取决于图像。我可以创建两个单独的函数来避免if语句,但我好奇地想知道效率对效率的影响是使用函数指针而不是if语句。如果为true,它将指向内联函数,如果为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();

  }
}

这可能比if语句快吗?我的猜测是否定的,因为内联将无用,因为编译器不知道在编译时要内联哪个函数和函数指针地址解析比if语句慢。

我已经对我的程序进行了描述,而且当我运行程序时,我预期会出现明显的差异......我没有遇到明显的差异。所以我只是出于好奇而想知道。

2 个答案:

答案 0 :(得分:8)

if语句很可能比调用函数更快,因为if只是一个短跳转而不是函数调用的开销。

此处已讨论过:Which one is faster ? Function call or Conditional if Statement?

“inline”关键字只是提示编译器告诉它在组装时尝试将指令内联。如果使用指向内联的函数指针,则无论如何都不能使用内联优化:

阅读:Do inline functions have addresses?

如果您觉得if语句的速度太慢,可以使用单独的while语句完全消除它:

if (trueorfalse) {
    while (kazillion) {
        trueFunction();
        dootherstuff();
    }
} else {
    while (kazillion) {
        dootherstuff();
    }
}

答案 1 :(得分:1)

注意1:我并没有故意回答上述问题。如果想通过上例中的指针想知道if语句和函数调用之间的速度有多快,那么mbonneau给出了一个非常好的答案。

注意2:以下是伪代码。

除了好奇心,我真的认为不应该问自己if语句和函数调用之间的优化速度是什么,以优化他的代码。增益肯定会非常小,结果代码可能会以一种可能影响可读性和维护的方式扭曲。

对于我的研究,我确实关心表现,这是我必须坚持的基本概念。但我更关心代码维护,如果我必须在良好的结构和轻微的优化之间做出选择,我肯定会选择好的结构。然后,如果是我,我会按照以下代码编写上述代码(避免if语句),使用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();

  }
}