Skip to content
Snippets Groups Projects
Commit d7dd088b authored by Martin Nolte's avatar Martin Nolte
Browse files

added a simple new / delete overload useful for small objects

[[Imported from SVN: r5247]]
parent 734c9ae0
No related branches found
No related tags found
No related merge requests found
......@@ -22,7 +22,7 @@ commoninclude_HEADERS = dlist.cc alignment.hh \
collectivecommunication.hh mpihelper.hh singleton.hh \
mpicollectivecommunication.hh geometrytype.hh utility.hh \
bartonnackmanifcheck.hh binaryfunctions.hh lru.hh fassign.hh \
static_assert.hh
static_assert.hh smallobject.hh
if EXPRESSIONTEMPLATES
commoninclude_HEADERS += exprtmpl.hh exprtmpl/scalar.inc exprtmpl/exprexpr.inc
......
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_SMALLOBJECT_HH
#define DUNE_SMALLOBJECT_HH
#include <new>
namespace Dune
{
// SmallObjectPool
// ---------------
class SmallObjectPool
{
union Block
{
Block *next;
unsigned int blocks;
};
public:
enum { blockSize = sizeof( Block ) };
enum { maxBlocks = (1 << 10) - 1 };
enum { maxSize = maxBlocks * blockSize };
private:
Block *list_[ maxBlocks ];
SmallObjectPool ()
{
for( unsigned int i = 0; i < maxBlocks; ++i )
list_[ i ] = 0;
}
~SmallObjectPool ()
{
for( unsigned int i = 0; i < maxBlocks; ++i )
delete list_[ i ];
}
static SmallObjectPool &instance ()
{
static SmallObjectPool inst;
return inst;
}
static Block *&list ( unsigned int blocks )
{
return instance().list_[ blocks ];
}
public:
static void *allocate ( unsigned int size )
{
const unsigned int blocks = (size + (blockSize-1)) / blockSize;
if( blocks > maxBlocks )
return 0;
Block *blockPtr = list( blocks );
if( blockPtr != 0 )
list( blocks ) = blockPtr->next;
else
blockPtr = new Block[ blocks+1 ];
blockPtr->blocks = blocks;
return blockPtr+1;
}
static void free ( void *ptr )
{
if( ptr != 0 )
{
Block *blockPtr = reinterpret_cast< Block * >( ptr ) - 1;
const unsigned int blocks = blockPtr->blocks;
blockPtr->next = list( blocks );
list( blocks ) = blockPtr;
}
}
};
// SmallObject
// -----------
struct SmallObject
{
void *operator new ( size_t size )
{
return SmallObjectPool :: allocate( size );
}
void operator delete ( void *ptr )
{
SmallObjectPool :: free( ptr );
}
};
}
#endif
......@@ -39,3 +39,4 @@ testfassign1
testfassign2
testfassign3
testfassign4
smallobject
......@@ -5,6 +5,7 @@ TESTPROGS = parsetest test-stack arraylisttest smartpointertest \
poolallocatortest settest gcdlcmtest streamtest \
bigunsignedinttest mpihelpertest singletontest mpicollcomm \
utilitytest lrutest \
smallobject \
testfassign1 testfassign2 testfassign3 \
testfassign4 \
testfassign_fail1 testfassign_fail2 testfassign_fail3\
......@@ -22,6 +23,8 @@ check_PROGRAMS = $(TESTPROGS)
AM_LDFLAGS = $(LOCAL_LIBS)
smallobject_SOURCES = smallobject.cc
# define the programs
bigunsignedinttest_SOURCES=bigunsignedinttest.cc
......
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#include <config.h>
#include <iostream>
#include <dune/common/timer.hh>
#include <dune/common/smallobject.hh>
using namespace Dune;
class A
{
int a_;
public:
A( int a )
: a_( a )
{}
};
class B
: public SmallObject
{
int b_;
public:
B( int b )
: b_( b )
{}
};
int main ( int argc, char **argv )
{
Timer timer;
const unsigned long iterations = 1 << 30;
std :: cout << "Performing " << iterations << " iterations." << std :: endl;
timer.reset();
for( unsigned long i = 0; i < iterations; ++i )
{
A *a = new A( (int)i );
delete a;
}
double timeA = timer.elapsed();
std :: cout << "Time without SmallObject: " << timeA << std :: endl;
timer.reset();
for( unsigned long i = 0; i < iterations; ++i )
{
B *b = new B( (int)i );
delete b;
}
double timeB = timer.elapsed();
std :: cout << "Time with SmallObject: " << timeB << std :: endl;
std :: cout << "Result: SmallObject is " << (timeA / timeB) << " times faster." << std :: endl;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment