Skip to content

Instantly share code, notes, and snippets.

@sahib
Created March 27, 2012 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sahib/2215782 to your computer and use it in GitHub Desktop.
Save sahib/2215782 to your computer and use it in GitHub Desktop.
(Silly) Per-Type-based Mempool
// g++ MemPool.cc $(pkg-config --libs --cflags glib-2.0) -Wall -Wextra -pedantic
#include <glib.h>
#include <algorithm>
template<class StorageClass>
class UseMemPool
{
public:
void * operator new(size_t size)
{
g_assert(size >= sizeof(gpointer));
gpointer mem = NULL;
if((mem = g_trash_stack_pop(&memstack)) == NULL) {
//g_message("Allocating.");
mem = g_slice_alloc(size);
}
return mem;
}
////////////////////////////
void operator delete(void * ptr)
{
g_trash_stack_push(&memstack,ptr);
}
////////////////////////////
/*
* WARNING: This only works fine when real slice allocation can be used.
* If g_malloc() is used freeing memory will cause weird beahviour / memory leaks.
* Memory allocation can be influenced by the G_SLICE Env variable.
*/
static void prealloc(size_t n_iterations = 128)
{
gsize memsize = sizeof(StorageClass) * n_iterations;
gpointer memdata = g_slice_alloc(memsize);
for(unsigned off = 0; off < memsize; off += sizeof(StorageClass))
operator delete (((char*)memdata) + off);
}
////////////////////////////
static void disposeAll()
{
g_slice_free_chain(GTrashStack,memstack,next);
memstack = NULL;
}
////////////////////////////
private:
static GTrashStack * memstack;
};
template<class StorageClass>
GTrashStack * UseMemPool<StorageClass>::memstack = NULL;
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
class SomeClass : public UseMemPool<SomeClass>
{
char buf[1024];
};
////////////////////////////////////////
class SomeClassWithoutMemPool
{
char buf[1024];
};
////////////////////////////////////////
int main()
{
double t1, t2;
const int iterations = 500000;
GTimer * watch = g_timer_new();
//SomeClass::prealloc(iterations);
g_timer_stop(watch);
g_print("%f seconds for prealloc()\n",g_timer_elapsed(watch,NULL));
g_timer_start(watch);
{
SomeClass * mem_ptr[iterations];
for(int i = 0; i < 10; i++)
{
for(int i = 0; i < iterations; i++)
mem_ptr[i] = new SomeClass;
for(int i = 0; i < iterations; i++)
delete mem_ptr[i];
}
}
g_timer_stop(watch);
t1 = g_timer_elapsed(watch,NULL);
g_timer_start(watch);
{
SomeClassWithoutMemPool * mem_ptr[iterations];
for(int i = 0; i < 10; i++)
{
for(int i = 0; i < iterations; i++)
mem_ptr[i] = new SomeClassWithoutMemPool;
for(int i = 0; i < iterations; i++)
delete mem_ptr[i];
}
}
g_timer_stop(watch);
t2 = g_timer_elapsed(watch,NULL);
g_print("%f seconds with mempool\n",t1);
g_print("%f seconds without mempool\n",t2);
g_print("%f Difference, Speedup: %2.3f%%\n",t2-t1, t2/t1 * 100);
g_print("%f seconds in total\n",t1+t2);
g_timer_start(watch);
SomeClass::disposeAll();
g_timer_stop(watch);
g_print("%f seconds to clean up\n",g_timer_elapsed(watch,NULL));
g_timer_destroy(watch);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment