(From TestTypesInsteadOfDispatch)
Before we jump to any conclusions about the results of this code, we need Sunir to come verify that it is a fair test.
It isn't. I'll have to carve out some time to demonstrate what I mean, but that isn't likely to happen while I have a deadline next week ;) --ss
In dispatch.cpp:
#include<iostream> #include<ctime> class Timeable { public: clock_t run() { clock_t start = ::clock(); for (int i = 0; i < 5000000; i++) reallyRun(); // (Template pattern) clock_t end = ::clock(); return end - start; } virtual void reallyRun() = 0; }; class NormalDispatchTimer: public Timeable { public: class NormalClass { public: virtual void run() = 0; }; // It would probably work with just one derived class, but just in case... class FirstNormalClass: public NormalClass { public: void run() { /* */ } }; class SecondNormalClass: public NormalClass { public: void run() { /* */ } }; void reallyRun() { first.run(); second.run(); } private: FirstNormalClass first; SecondNormalClass second; }; class ManualDispatchTimer: public Timeable { public: void reallyRun() { runOn(&first); runOn(&second); } class ManualClass { public: enum TYPE { FirstType, SecondType, }; unsigned char type; }; class FirstManualClass: public ManualClass { public: FirstManualClass(): type(FirstType) { } unsigned char type; int someData; }; class SecondManualClass: public ManualClass { public: SecondManualClass(): type(SecondType) { } unsigned char type; int someOtherData; }; inline void runOn(ManualClass* mcp) { int x; if (ManualClass::FirstType == mcp->type) x = ((FirstManualClass*)mcp)->someData; else if (ManualClass::SecondType == mcp->type) x = ((SecondManualClass*)mcp)->someOtherData; } private: FirstManualClass first; SecondManualClass second; }; int main() { std::cout << "Normal: " << NormalDispatchTimer().run() << std::endl << "Manual: " << ManualDispatchTimer().run() << std::endl; }
In the Makefile:
default: plain optimized ./plain ./optimized plain: *.cpp g++ $< -o plain optimized: *.cpp g++ -O3 $< -o optimized