c++virtualfunctorboost-function

Choosing between virtual function, function_pointer and functors


I am writing a class in which a one of the function's implementation depends on the users. Currently I have it as a virtual function and users need to override my class to provide its implementation. I am thinking of making it a functor(boost::function)/function_pointer so that users can register to it. Application is extremely performance critical and speed is more important than the classes looking nice. Is changing to functors give some performance benefit?

In most cases, it will be a free function so a function pointer should be fine. But I guess there would be some cases where state may be required and hence it needs to be a functor.

Will I get any preformance benefit by allowing to register either a function_ptr or a functor and calling the appropriate one based on some bool? Something similar to this.

class Myclass
{
   public:
    registerFuncPtr(FuncPtrSignature);
    registerFunctor(boost::function func);
   private:    
   someMethod(someArgs)
   {
    ...
    if(_isFuncPtr)
        _func_ptr(args);
    else
        _functor(args);
    ...
   }
   bool _isFuncPtr;
   FuncptrSignature _func_ptr;
   boost::function _functor;
}

Update:

I am writing a shared library and the clients would dynamically link against it. No C++0x. :(


Solution

  • If you are after performance, go with naked function pointers. If you need state, provide a separate state argument of type void* in your function, and let the users register their state. There's no magic that can make any C++ construct to be faster than that, since functors and virtual functions and all the rest are all just function pointers wrapped in a more or less type-safe envelope.

    More importantly, when talking about optimization, you should no trust anything whatsoever but your profiler (this includes the paragraph above BTW).

    Inlining could in theory improve the performance, but the users' functions cannot be inlined (a compiler cannot inline code that hasn't been written yet). If you don't compile your library, but distribute it as source code, there's a possibility of some performance benefit due to inlining. As always, only a profiler can tell.

    One case when a function object is likely to outperform a function pointer is passing them to a function template. If the template itself is not getting inlined, then the function object is likely to get inlined inside the template instantiation, and the function pointer is not.