什么是更快:检查空指针或调用空函数?

时间:2015-07-28 14:26:37

标签: c++

我正在构建一个系统,根据用户输入,我必须多次调用一些命令,例如

void handle(int MouseInput)
{
    switch(MouseInput)
    {
    case Move:  
        ActionMove->execute(); 
        // ...
    case BtnUp: 
        ActionBtnUp->execute(); 
        // ...
    }
}

然而,由于系统是可参数化的,我并不总是拥有例如actionMove命令对象(有时我在Move上什么都不做)。

什么更快:

  • 实现空对象模式,即具有execute函数的对象,如此

    execute() {}
    
  • 或者每次检查空指针:

    if (ActionBtnUp) ActionBtnUp->execute(); 
    

我要问的是什么是更大的开销,跳转到一个什么都不做的函数的成本(编译器可能很容易优化它)或者每次检查一个空指针?

注意我现在只能测试小规模,看不出任何差异。如果是这种情况,我想知道。

4 个答案:

答案 0 :(得分:5)

在这种情况下,除非您注意到性能问题,或者您每隔几秒钟就会这样做几千次,否则它可能对性能没有太大影响。做对你最有意义的事情,以及最可实现和最清晰的事情。这样做在维护期间节省的时间可能大于程序花费额外比较的总时间。

答案 1 :(得分:4)

为了让ActionBtnUp能够指向可能具有空execute()的东西,或者可能指向可能真正做某些有用的东西,您需要它指向基类并且使execute()虚拟。

为了使编译器能够优化该调用,它必须能够静态地证明指针指向哪种派生类型。如果它可以做到这一点,它可能会告诉指针何时为空并删除检查。因此,编译器优化也不会更容易。

如果execute()函数不是虚拟的,那么将其更改为虚拟并添加新的类类型只是为了避免空指针检查可能是一个坏主意。您应该在对行为变化有意义时使用虚函数,而不仅仅是微优化空指针检查。

答案 2 :(得分:3)

首先优化代码可理解性。只有在您知道自己遇到问题后才能优化执行速度。根据我的经验,结构良好的代码与良好的引用位置松散耦合,往往也是非常快速的代码。如果不出意外,编译器更容易优化。

就可理解性而言,空对象模式可能更好 - 您只在一个地方测试null。在每次取消引用之前测试null似乎违反了“不要重复自己”#34;。

答案 3 :(得分:0)

您的ActionMove是否有效是否有意义?如果答案是肯定的,我相信你应该测试空指针。如果它不应该为null,只需使用引用,不要测试空指针。