Created
March 27, 2012 13:19
-
-
Save sahib/2215782 to your computer and use it in GitHub Desktop.
(Silly) Per-Type-based Mempool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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