通过使用函数指针来切割if语句会更有效吗?

bob*_*obo 6 c++ performance function-pointers data-oriented-design

因此,有这个规则试图if从高重复循环中提取语句:

for( int i = 0 ; i < 10000 ; i++ )
{
    if( someModeSettingOn )  doThis( data[i] ) ;
    else  doThat( data[i] ) ;
}
Run Code Online (Sandbox Code Playgroud)

他们说,最好将其分解,将if语句放在外面:

if( someModeSettingOn )
  for( int i = 0 ; i < 10000 ; i++ )
    doThis( data[i] ) ;
else
  for( int i = 0 ; i < 10000 ; i++ )
    doThat( data[i] ) ;      
Run Code Online (Sandbox Code Playgroud)

(如果您说"Ho!不要自己优化!编译器会这样做!")确定优化器可能会为您执行此操作.但是在典型的C++废话中(我不同意他的所有观点,例如他对虚拟功能的态度)Mike Acton说:"为什么要让编译器猜测你知道的东西?对我来说,最好的点是那些胶粘物.

那么为什么不使用函数指针呢?

FunctionPointer *fp ;
if( someModeSettingOn )  fp = func1 ;
else fp = func2 ;

for( int i = 0 ; i < 10000 ; i++ )
{
    fp( data[i] ) ;
}
Run Code Online (Sandbox Code Playgroud)

函数指针是否有某种隐藏的开销?调用直接函数是否有效?

ink*_*boo 8

在这个例子中,不可能说哪种情况会更快.您需要在目标平台/编译器上分析此代码以进行估计.

一般而言,在99%的情况下,此类代码无需进行优化.这是邪恶的过早优化的例子.编写人类可读的代码并仅在分析后需要时对其进行优化.


Bra*_*vic 6

不要猜测,衡量.

但是,如果我绝对不得不猜测,我会说第三个变量(函数指针)将比第二个变量(if外部循环)慢,我怀疑它可能会更好地发挥CPU的分支预测.

第一个变体可能或可能不等同于第二个变体,这取决于编译器的智能程度,正如您已经注意到的那样.


Mar*_*k B 6

为什么让编译器猜测你知道的东西?

因为您可能会为未来的维护者复杂化代码,而不会给代码用户带来任何实际好处.这种变化强烈反映了过早的优化,只有在分析之后,我才会考虑除了明显的(if内部循环)实现之外的任何其他内容.

鉴于分析显示它是一个问题然后作为猜测我相信拉出if循环将比函数指针更快,因为指针可能添加编译器无法优化的间接级别.它还会降低编译器内联任何调用的可能性.

但是我也会考虑使用抽象接口而不是if循环内的替代设计.然后,每个数据对象都已知道自动执行的操作.