I wrote a simple example that estimates the average call time of a virtual function using the base class interface and dynamic_cast and calling a non-virtual function. Here he is:
#include <iostream> #include <numeric> #include <list> #include <time.h> #define CALL_COUNTER (3000) __forceinline int someFunction() { return 5; } struct Base { virtual int virtualCall() = 0; virtual ~Base(){}; }; struct Derived : public Base { Derived(){}; virtual ~Derived(){}; virtual int virtualCall(){ return someFunction(); }; int notVirtualCall(){ return someFunction(); }; }; struct Derived2 : public Base { Derived2(){}; virtual ~Derived2(){}; virtual int virtualCall(){ return someFunction(); }; int notVirtualCall(){ return someFunction(); }; }; typedef std::list<double> Timings; Base* createObject(int i) { if(i % 2 > 0) return new Derived(); else return new Derived2(); } void callDynamiccast(Timings& stat) { for(unsigned i = 0; i < CALL_COUNTER; ++i) { Base* ptr = createObject(i); clock_t startTime = clock(); for(int j = 0; j < CALL_COUNTER; ++j) { Derived* x = (dynamic_cast<Derived*>(ptr)); if(x) x->notVirtualCall(); } clock_t endTime = clock(); double callTime = (double)(endTime - startTime) / CLOCKS_PER_SEC; stat.push_back(callTime); delete ptr; } } void callVirtual(Timings& stat) { for(unsigned i = 0; i < CALL_COUNTER; ++i) { Base* ptr = createObject(i); clock_t startTime = clock(); for(int j = 0; j < CALL_COUNTER; ++j) ptr->virtualCall(); clock_t endTime = clock(); double callTime = (double)(endTime - startTime) / CLOCKS_PER_SEC; stat.push_back(callTime); delete ptr; } } int main() { double averageTime = 0; Timings timings; timings.clear(); callDynamiccast(timings); averageTime = (double) std::accumulate<Timings::iterator, double>(timings.begin(), timings.end(), 0); averageTime /= timings.size(); std::cout << "time for callDynamiccast: " << averageTime << std::endl; timings.clear(); callVirtual(timings); averageTime = (double) std::accumulate<Timings::iterator, double>(timings.begin(), timings.end(), 0); averageTime /= timings.size(); std::cout << "time for callVirtual: " << averageTime << std::endl; return 0; }
CallDynamiccast seems to be receiving almost twice as much.
time for callDynamiccast: 0.000240333
time for callVirtual: 0.0001401
Any ideas why?
EDITED: now the creation of the object is performed in the separete function, so compler does not know its real type. Almost the same result.
EDITED2: Create two different types of derived objects.
D_e
source share