#include #include #include #include const size_t NUM_CALLS = 10000000; //////////////////////////////// timing helpers //////////////////////////////// double GetSeconds() { return ( double )clock() / CLOCKS_PER_SEC; } void PrintElapsedTime( double ElapsedTime ) { printf( "%f s/Mcalls\n", float( ElapsedTime / double( NUM_CALLS / 10000000 ) ) ); } //////////////////////////////// adhoc intrusive smartpointer //////////////////////////////// class iIntrusiveCounter { public: iIntrusiveCounter():FRefCounter(0) {}; virtual ~iIntrusiveCounter() {} void IncRefCount() { FRefCounter++; } void DecRefCount() { if ( --FRefCounter == 0 ) { delete this; } } private: std::atomic FRefCounter; }; /// Intrusive smart pointer template class clPtr { public: /// default ctor clPtr(): FObject( 0 ) {} clPtr( const clPtr& Ptr ): FObject( Ptr.FObject ) { FObject->IncRefCount(); } clPtr( T* const Object ): FObject( Object ) { FObject->IncRefCount(); } ~clPtr() { FObject->DecRefCount(); } clPtr& operator = ( const clPtr& Ptr ) { T* Temp = FObject; FObject = Ptr.FObject; Ptr.FObject->IncRefCount(); Temp->DecRefCount(); return *this; } inline T* operator -> () const { return FObject; } private: T* FObject; }; //////////////////////////////// class clTestObject: public iIntrusiveCounter { public: clTestObject():FPayload(32167) {} void Do() { FPayload+=3; } private: int FPayload; }; //////////////////////////////// void ProcessByValue( clPtr O ) { O->Do(); } void ProcessByConstRef( const clPtr& O ) { O->Do(); } //////////////////////////////// int main() { clPtr Obj = new clTestObject; for ( size_t j = 0; j != 3; j++ ) { double StartTime = GetSeconds(); for ( size_t i = 0; i != NUM_CALLS; i++ ) { ProcessByValue( Obj ); } PrintElapsedTime( GetSeconds() - StartTime ); } printf( "\n" ); for ( size_t j = 0; j != 3; j++ ) { double StartTime = GetSeconds(); for ( size_t i = 0; i != NUM_CALLS; i++ ) { ProcessByConstRef( Obj ); } PrintElapsedTime( GetSeconds() - StartTime ); } return 0; }