MarsJupiter - Family shareware  
 
 Monday, 01 December 2008
A simple non standard allocator for C++ classes

The following code is for a non standard allocator, which like all non-standard allocators is geared towards some peculiarity of the calling code.

Of course this somewhat breaks the "purity" of the code, it ceases to be a transplantable blackbox capable of slotting into any project!

In this case we present an allocator for a class that expects many instances of itself to be allocated, but for the total number of allocations to periodically get back to zero. The code can be compiled in two version, one of which maintains a "free list" so that if the class gets frequently deallocated as well as allocated, the memory usage will not expand excessively. Alternatively you can compile without a free list, in which case when you delete an instance, that memory will not be resused again.

In our tests of using this in a real life product, we gained a 13.5% increase in processing speed without the free list, and 10% with the free list. Given that the code in question has quite a lot of work to do, aside from allocation, this is a pretty impressive increase.

Fragment of the DictionaryLetterArray.h file:

#ifdef NSA_DICTIONARY_LETTER_ARRAY
//
// Code for Non Standard allocator
//
#ifdef NSA_DICTIONARY_LETTER_ARRAY_FREE_LIST
#define NSA_DICTIONARY_LETTER_ARRAY_POOL_SIZE 50 // optimal pool size
static CDictionaryLetterArray *m_free_list; // keep a free list

#else
#define NSA_DICTIONARY_LETTER_ARRAY_POOL_SIZE 150 // optimal pool size
static int m_current_pool_pos; // simply allocate from current pool
static CDictionaryLetterArray *m_current_pool; // current pool
#endif
static void NewPool();
static void FreePools();
static int m_nsa_alloc_count;> // keep track of instances allocated so we can free pools when zero
static vectorm_pools; // remember pool so we can free them
static CComAutoCriticalSection m_thread_alloc_section; // use a critical section for thread safety
#ifdef DEBUG
void * operator new (size_t size/*,const char *file, int line*/)
#else
void * operator new (size_t size)
#endif
{
m_thread_alloc_section.Lock();
CDictionaryLetterArray *pItem;
#ifdef NSA_DICTIONARY_LETTER_ARRAY_FREE_LIST
if (m_free_list)
{
// we use a linked list of free items
// using the memory allocated to the class. Thus it is
// essential that the class is at least void * in length.
pItem = m_free_list;

m_free_list = *((CDictionaryLetterArray **)m_free_list);
}
else
{ NewPool();
pItem = m_free_list;
m_free_list = *((CDictionaryLetterArray **)m_free_list);

}
#else
// if no free list simply return next in pool, creating new pools as needed
if (m_current_pool_pos == 0)
{
NewPool();
}
pItem = (m_current_pool + m_current_pool_pos);
m_current_pool_pos = (m_current_pool_pos +1) % NSA_DICTIONARY_LETTER_ARRAY_POOL_SIZE;

#endif
m_thread_alloc_section.Unlock();
m_nsa_alloc_count++;
return (void *)pItem;
}
void operator delete (void * mem)
{
CDictionaryLetterArray *pItem = (CDictionaryLetterArray *)mem;
m_thread_alloc_section.Lock();

#ifdef NSA_DICTIONARY_LETTER_ARRAY_FREE_LIST

void **pFree = (void **)pItem;

*pFree = m_free_list;

m_free_list = pItem;
#endif
m_nsa_alloc_count --;
if (!m_nsa_alloc_count)
{
FreePools();
}

m_thread_alloc_section.Unlock();
}


#endif

A fragment of the DictionaryLetterArray.cpp file

#ifdef NSA_DICTIONARY_LETTER_ARRAY
CComAutoCriticalSection CDictionaryLetterArray::m_thread_alloc_section;
int CDictionaryLetterArray::m_nsa_alloc_count=0;
vector CDictionaryLetterArray::m_pools;

#ifndef NSA_DICTIONARY_LETTER_ARRAY_FREE_LIST


int CDictionaryLetterArray::m_current_pool_pos = 0;
CDictionaryLetterArray * CDictionaryLetterArray::m_current_pool = NULL;
#else

CDictionaryLetterArray * CDictionaryLetterArray::m_free_list = NULL;

#endif

void CDictionaryLetterArray::FreePools()
{


for (int i = 0; i < m_pools.size();i++)
{
void *pPool = m_pools[i];

free(pPool);
}
m_pools.clear();

#ifndef NSA_DICTIONARY_LETTER_ARRAY_FREE_LIST
m_current_pool_pos = 0;
#else
m_free_list = NULL;
#endif

}

void CDictionaryLetterArray::NewPool()
{

CDictionaryLetterArray *pPool = (CDictionaryLetterArray *) malloc(NSA_DICTIONARY_LETTER_ARRAY_POOL_SIZE * sizeof(CDictionaryLetterArray));

m_pools.push_back((void *)pPool);
#ifdef NSA_DICTIONARY_LETTER_ARRAY_FREE_LIST

for (int i = 0; i < NSA_DICTIONARY_LETTER_ARRAY_POOL_SIZE; i++)
{
CDictionaryLetterArray *pItem = (CDictionaryLetterArray *)(pPool + i);
void **pFree = (void** )pItem;
*pFree = (void *)m_free_list;
m_free_list = pItem;

}

_ASSERT(m_free_list);
#else
m_current_pool = pPool;
#endif
}

#endif

 
Products

Callisto - Newsreader/Bulletin Board Browser. The best way to
browse usenet and bulletin boards.
Newsreader/BBS Browser


Foboz - Meta Search Engine, The best Meta Search Engine, searching
hundreds of search engines from the best sites across the web.
Meta Search Engine


 

ThereIWas - Intelligent Favorites/History Toolbar for internet
Explorer
Favorites/History Toolbar


 

WhereWasi? - History Word Search Toolbar for Internet Explorer
History Word Search Toolbar

Main Menu
Home
MarsJupiter Products
Callisto Newsreader - News Reader/Forum Browser
Foboz Meta Search Engine - Unbeatable Results
Where Was I?
ThereIWas - intelligent history/favorites
UpFront - Ingres FRS GUI
Company News
Contact Us
FAQ
MarsJupiter Forums
Affiliate Programme
Alex Programming
Resources
The Web Links
The Daily Blat
Newsflash
Current Releases
Callisto News Reader/Bulletin Board Browser 3.14 has now been released:
Download Callisto here
Tucows rating:
Foboz Meta Search Engine 1.52 has been released:
Download Foboz here
Tucows rating:
WhereWAsI? - Internet Explorer history search toolbar 1.50 has been released:
Download WhereWasI? here
AuntyJean - Internet Explorer family friendly Filter toolbar 1.00 has been released:
Download AuntyJean here
ThereIWas- Intelligent Favorites/history Internet Explorer toolbar 1.02 has been released:
Download ThereIWas here
Coop Ad Link Module
Montana Music|Home Insurance|Loans|Auto Loans|Virtual Pets Blog
 
Go to top of page  Home | MarsJupiter Products | Callisto Newsreader - News Reader/Forum Browser | Foboz Meta Search Engine - Unbeatable Results | Where Was I? | ThereIWas - intelligent history/favorites | UpFront - Ingres FRS GUI | Company News | Contact Us | FAQ | MarsJupiter Forums | Affiliate Programme | Alex Programming | Resources | The Web Links | The Daily Blat |