1

I've come across to an Alexandrescu tutorial about traits and I have some reflections to share. This is the code:

// Example 6: Reference counting traits
//
template <class T>
class RefCountingTraits
{
    static void Refer(T* p)
    {
    p->IncRef(); // assume RefCounted interface
    }

    static void Unrefer(T* p)
    {
    p->DecRef(); // assume RefCounted interface
    }
};

template <>
class RefCountingTraits<Widget>
{
    static void Refer(Widget* p)
    {
    p->AddReference(); // use Widget interface
    }
    static void Unrefer(Widget* p)
    {
    // use Widget interface
    if (p->RemoveReference() == 0)
        delete p;
    }
};

How much overhead we have in this case compared to a standard virtual function member case? we are not accessing directly to the object also in this case: we are still passing a pointer. Is the compiler able to optimize it in same way?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
user3770392
  • 453
  • 5
  • 12

1 Answers1

1

At typical production optimisation levels (-O2 or /O2) you can expect all the code you've shown to be inlined and the bits without side-effects optimised away. That leaves the actual calls to IncRef or AddReference and the check for and delete-ion.

If virtual functions had been used, and if the reference counting code is trivial (e.g. not thread safe), it might have been about an order of magnitude slower due to a dispatch table lookup and out-of-line function call, but that will vary a bit with compiler, exact optimisation settings, CPU, calling conventions etc..

As always, when you have to care, profile and experiment.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • if I've understood well, that code when optimized will be like calling directly p->IncRef(), without the pointer copy right? it seems too much one order of magnitude. Full agree about profiling :) – user3770392 Mar 09 '17 at 16:04
  • *"...right?"* right. *"too much one order of magnitude"* - even contrasting calling a trivial function selected by a run-time switch vs. virtual dispatch gave a 9.2x factor in [this benchmark](http://stackoverflow.com/a/4801861/410767), but always good to measure and share your own benchmark code / findings. In this case, the `IncRef()` `DecRef()` are probably not so trivial when thread safety is needed, so the impact of additional virtual dispatch will be a smaller factor. – Tony Delroy Mar 10 '17 at 01:27