BDE 4.14.0 Production release
|
Provide an efficient managed allocator using a local buffer.
This component provides a concrete mechanism, bdlma::LocalSequentialAllocator
, that implements the bdlma::ManagedAllocator
protocol to very efficiently allocate heterogeneous memory blocks (of varying, user-specified sizes) from a local buffer. Note that it derives from bdlma::BufferedSequentialAllocator
so that the implementations of allocate
, deallocate
, and release
don't need to be instantiated for each user-specified size.
If an allocation request exceeds the remaining free memory space in the local buffer, the allocator will fall back to a sequence of dynamically-allocated buffers. The release
method releases all memory allocated through the allocator, as does the destructor. Note that, even though a deallocate
method is available, it has no effect: individually allocated memory blocks cannot be separately deallocated.
bdlma::LocalSequentialAllocator
is typically used when users have a reasonable estimation of the amount of memory needed. This amount of memory would then be created directly on the program stack, and used as the local buffer by this allocator for very fast memory allocation. Whilst the buffer has sufficient capacity, memory allocations will not trigger any dynamic memory allocation, will have optimal locality of reference, and will not require deallocation upon destruction.
Once the local buffer is exhausted, subsequent allocation requests require dynamic memory allocation, and the performance of the allocator degrades.
The main difference between a bdlma::LocalSequentialAllocator
and a bdlma::BufferedSequentialAllocator
is that this class internally maintains a buffer, rather than being given one at construction time.
This section illustrates intended use of this component.
Suppose we have a function which takes a map of items to update in some database:
We call this method a lot, and after profiling, we notice that it's contributing a significant proportion of time, due to the allocations it is making. We decide to see whether a LocalSequentialAllocator would help.
First, use a bslma::TestAllocator
to track the typical memory usage:
Then we run our program again, and observe the following output:
It looks like 129 is a good choice for the size of our allocator, so we go with that:
Note that we release at the end of every iteration, as the deallocate method is a no-op, so without this, subsequent memory would be allocated from the default allocator (or the allocator passed to bsa
at construction).
Finally, we re-profile our code to determine whether the addition of a LocalSequentialAllocator
helped.