Boost logo

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