什么更快:noop函数调用还是if语句?

3

我得到了一个用于删除的函数指针,但大多数情况下,这个删除器是不需要的,只有在我维护某些东西的内部副本时才需要。目前,我使用一个无操作的删除器函数来实现:

class MyClass{
public:
  // bind object
  template<class Type>
  void Bind(Type* obj){
    Cleanup();
    object_ = obj;
  }

  // bind object with internal copy
  template<class Type>
  void Bind(Type obj){
    Cleanup();
    object_ = new Type(obj);
    deleter = &Deleter<Type>;
  }

private:
  template<class Type>
  static void Deleter(void* obj_ptr){
    Type* obj = static_cast<Type*>(obj_ptr);
    delete obj;
  }

  static void NoopDeleter(void* unused){
  }

  void Cleanup(){
    (*deleter_)(object_);
    object_ = 0;
    deleter_ = &NoopDeleter;
  }

  typedef void (*DeleterFunc)(void*);

  void* object_;
  DeleterFunc deleter_;
};

现在另一个明显的选择是在不需要时将其设置为0,并在Cleanup函数中使用if(deleter_ != 0) (*deleter_)(object_)进行检查。
现在在编码过程中,我突然想到:"嗯,哪个版本会更快?",所以这更多地是出于个人兴趣而不是优化。如果问题听起来有点蠢,请谅解,但它让我困扰,我真的想知道。先谢谢你们的回答!

3
任何“哪个更快”的问题的答案都是通过测量来得出。由于有太多的变量,很难得出一般性的结论。尤其是测试两种可能性实际上比在论坛上提问还要容易! - Mark Ransom
2个回答

3

函数调用必须设置一个堆栈帧。而if语句只需要执行一条机器指令,也许会有两个,这取决于机器的架构。


获取函数指针,处理参数,从无操作函数返回... - Jonathan Leffler
可能还会使用RET指令来引起该内存页面的页面错误。 :) - Vagrant
一个空函数需要多少个堆栈帧?没有吗?if语句也必须处理指针,所以我认为你在那里并没有节省多少。@Xeo:只需进行测量,并告诉我们差异是1还是2纳秒! - Bo Persson

1
与函数调用相比,将变量与0进行比较会更快(通常只需一个时钟周期),特别是考虑到变量必须加载到寄存器中才能进行函数调用。开销包括调整堆栈、推送object_和返回地址、调用函数等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接