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 templatestruct 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.
0 comments:
Post a Comment