|
Boost : |
From: davidbien_at_[hidden]
Date: 2000-04-18 01:09:26
Whether or not anyone cares... ( it is my curiosity anyway :-)
I have completed a performance test similar to the non-polymorphic
one described in a previous post. Not surprisely, the shared_ptr<T>
implementation performed almost exactly the same as in the non-
polymorphic version. The polymorphic reference object container was
slower than the non-polymorphic version, but was still slightly
faster than shared_ptr<T>.
shared_ptr<T> is much easier to understand and use than my reference
object implementation, which is certainly aided with typedefs.
Of course, if you want to use allocators, you can't really use
shared_ptr<T>.
Here are some timing results:
shared_ptr<T> with SGI STL's pool allocator used in set<>
C:\src\testtmpl\Release>testboostp 100 10000 10000
Total: [25640] Average[256].
C:\src\testtmpl\Release>testboostp 100 10000 10000
Total: [26426] Average[264].
C:\src\testtmpl\Release>testboostp 100 10000 10000
Total: [25906] Average[259].
C:\src\testtmpl\Release>testboostp 100 10000 10000
Total: [26046] Average[260].
reference counted objects using SGI STL's pool allocator
C:\src\testtmpl\Release>testrcopv 100 10000 10000
Total: [24146] Average[241].
C:\src\testtmpl\Release>testrcopv 100 10000 10000
Total: [23730] Average[237].
C:\src\testtmpl\Release>testrcopv 100 10000 10000
Total: [24071] Average[240].
C:\src\testtmpl\Release>testrcopv 100 10000 10000
Total: [22257] Average[222].
Here is the code shared between both implementations:
// Store polymorphic objects based on Base:
struct Base
{
bool operator < ( const Base & _r ) const
{
return GetDoubleValue() < _r.GetDoubleValue();
}
virtual double GetDoubleValue() const = 0;
};
template < class t_Ty >
struct Derived : public Base
{
t_Ty m_t;
Derived( t_Ty const & _t )
: m_t( _t )
{
}
double GetDoubleValue() const
{
return m_t;
}
};
int
main( int argc, char ** argv )
{
if ( argc < 4 )
{
cerr << "main(): usage\n" << argv[0] << "<num iterations> <num
elements> <rand seed>\n";
return -1;
}
int iIterations = atoi( argv[1] );
int iNumElems = atoi( argv[2] );
int iRandSeed = atoi( argv[3] );
srand( iRandSeed );
//typedef _TyMallocAllocator _TyAllocator;
typedef allocator< char > _TyAllocator;
Here is the shared_ptr<> code:
typedef shared_ptr< Base > _TySharedBase;
typedef set< _TySharedBase,
less< _TySharedBase >, _TyAllocator > _TySetBases;
DWORD dwStart = GetTickCount();
int iNumIter = iIterations;
while ( iIterations-- )
{
_TySetBases setBases;
_TySharedBase sb;
for ( int _i = 0; _i < iNumElems; ++_i )
{
switch( rand() % 2 )
{
case 0:
{
sb.reset( new Derived< int >( rand() ) );
}
break;
case 1:
{
sb.reset( new Derived< double >( rand() ) );
}
break;
}
setBases.insert( sb );
}
}
DWORD dwTotal = GetTickCount() - dwStart;
cout << "Total: [" << dwTotal << "] Average["
<< ( dwTotal / iNumIter ) << "].\n";
return 0;
}
Here is the reference counted object code:
typedef _gcop_base< Base, kfUseElementCompare > _TyGcoBase;
typedef _gcp< Base, _TyGcoBase, kfCopyOnWrite > _TyGcpBase;
typedef _gcr< Base, _TyGcoBase, kfCopyOnWrite > _TyGcrBase;
typedef set< _TyGcrBase,
less< _TyGcrBase >, _TyAllocator > _TySetBases;
DWORD dwStart = GetTickCount();
int iNumIter = iIterations;
while ( iIterations-- )
{
_TySetBases setBases;
// Can't have a null reference, so need to insert a pointer:
_TyGcpBase gcpBase;
for ( int _i = 0; _i < iNumElems; ++_i )
{
switch( rand() % 2 )
{
case 0:
{
typedef _gcop_derived< Derived< int >, Base,
_TyAllocator, _TyGcoBase > _TyGcoDerivedInt;
_TyGcoDerivedInt::CreateGct1( gcpBase, rand() );
}
break;
case 1:
{
typedef _gcop_derived< Derived< double >, Base,
_TyAllocator, _TyGcoBase > _TyGcoDerivedDouble;
_TyGcoDerivedDouble::CreateGct1( gcpBase, rand() );
}
break;
}
setBases.insert( gcpBase );
}
}
DWORD dwTotal = GetTickCount() - dwStart;
cout << "Total: [" << dwTotal << "] Average["
<< ( dwTotal / iNumIter ) << "].\n";
return 0;
}
bien
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk