Wednesday, June 15, 2011

Benchmarking function call overhead in C++

Download: benchmark.tar.gz

The are two types of function calls I benchmark here:

1) Virtual functions
2) CRTP, used to simulate dynamic binding (with and without inlining)

One particular use of the CRTP is to simulate dynamic binding. The technique achieves a similar effect to the use of virtual functions, without the costs of dynamic polymorphism. The reason for this stems from the ability to inline function calls which is not possible with virtual functions bound at run-time. The use of CRTP is only worthwile when the cost of calling a funcion is not dominated by call and return overhead. Getter and Setter funcionts are good candidates for inlined CRTP.

Dynamic.h

#ifndef _Dynamic_H
#define _Dynamic_H

struct DynamicBase
{
    DynamicBase() {}
    virtual ~DynamicBase() {}
    virtual void function(long*) = 0;
};

DynamicBase* createDynamic();

#endif  /* _Dynamic_H */
Dynamic.cc
#include "Dynamic.h"
struct ImpOfDynamic : public DynamicBase
{
    void function(long* x);
};

void ImpOfDynamic::function(long* x) { ++*x; }

DynamicBase* createDynamic() {
    return new ImpOfDynamic;
}
Static.h
#ifndef _Static_H
#define _Static_H

template 
struct StaticBase
{
    void function(long* x)
    {
        static_cast(this)->function(x);
    }
};

struct ImpOfStatic : StaticBase
{
    // Without inlining  
    // void function(long* x);    

    // With inlining 
    inline void function(long* x);
};

void ImpOfStatic::function(long* x) { ++*x; }

#endif

main.cc
#include "Static.h"
#include "Dynamic.h"
#include 
#include 

Benchmark Results:

Without CRTP inlining:
6.01975 Virtual function (ns)
6.0212 CRTP function (ns)

With CRTP inlining:
6.16391 Virtual function (ns)
1.99611 CRTP function (ns)

There is no point in using CRTP instead of virtual functions unless inlining is used.

Socializer Widget By Blogger Yard
SOCIALIZE IT →
FOLLOW US →
SHARE IT →

0 comments:

Post a Comment