C++ 避免if语句的内联函数指针

C++ 避免if语句的内联函数指针,c++,optimization,function-pointers,inline,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 f

在我的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语句慢


我已经分析了我的程序,虽然我希望在运行我的程序时会有明显的不同。。。我没有感受到明显的不同。因此,出于好奇,我只是想知道。

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

这里讨论了这一点:

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

阅读:

如果您觉得If语句速度过慢,可以使用单独的while语句将其完全消除:

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

警告1:我不是故意回答上述问题的。如果想知道在上面的例子中,If语句和通过指针的函数调用之间的速度有多快,那么mbonneau给出了一个很好的答案

警告2:以下是伪代码

除了好奇,我真的认为人们不应该问自己if语句和函数调用之间的速度有多快来优化代码。增益肯定非常小,结果代码可能会被扭曲,从而影响可读性和维护

在我的研究中,我确实关心性能,这是我必须坚持的一个基本概念。但是我更关心代码维护,如果我必须在一个好的结构和一个轻微的优化之间做出选择,我肯定会选择好的结构。然后,如果是我,我将按照如下方式编写上述代码(避免使用if语句),通过一个

classmystrategy{
公众:
虚空MyFunction(Stuff&)=0;
};
课堂策略一:公共秘密策略{
公众:
void MyFunction(Stuff&);//做点什么
};
课堂策略二:公共秘密策略{
公众:
void MyFunction(Stuff&Stuff){}//什么都不做,如果
//你可以改变主意
//以后做点什么。
};
类jpg{
公众:
jpg(MyStrategy&strat):strat(strat){}
void func(Stuff&Stuff){return strat.MyFunction(Stuff);}
私人:
...
神秘战略;
}
main(){
jpg a(新策略一);;
jpg b(新战略二);
向量v{a,b};
用于(自动e:v)
{
e、 func();
dootherstuff();
}
}

您是否知道?这是为您准备的吗?我已经意识到我应该完全避免使用if语句,因为它将始终为真或为假。@deanresin您应该遵循命名约定:
trueorfalse
dootherstuff
@deanresin我并不是要避免使用
if
语句,或者像mbonneau建议的那样,将循环放入其中;我只是想说分支预测可以解释为什么你们并没有看到太大的差异。(好吧,这可能是因为
if
语句和指针分辨率比所分析的函数体要轻得多。)@Mike我认为我的if语句/指针分辨率相对于函数体其余部分的权重是正确的。也。。用你的话来说。。我没有注意到差异,可能是因为CPU的分支预测正在缓解任何潜在的减速;这两个问题都需要解决,而解决方案会让事情变得缓慢。这不是真的吗?@迈克:是的,这是真的。事实上,我并不是真的在回答这里提出的问题,我应该在我的回答中详细说明这一点(我现在就做)。我的观点是,即使人们真的关心性能(像我一样),我也不确定在优化代码时,在if语句和函数指针之间寻找更快的方法是正确的。但事实并非如此,因为deanresin明确表示这是为了满足他/她的好奇心。
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();

  }
}