Le probabilità sono che questo non sia un problema. L'allocazione di Deque
avviene comunque in blocchi, quindi sarà possibile riallocarne solo poche volte. Hai determinato che questo è un collo di bottiglia?
Ad ogni modo, lo standard non fornisce un accessor al contenitore `queue ', perché ciò vanificherebbe lo scopo dell'incapsulamento.
Se sei davvero preoccupato, il pool si alloca. Ciò significa preallocare la memoria in anticipo, quindi quando il contenitore richiede memoria, è già lì. Non riesco a superare gli allocatori e parenti, sarebbe eccessivo per una risposta SO, ma cercare allocators on Google.
Fondamentalmente, puoi dire al tuo contenitore da dove ottenere la memoria. Normalmente, questo è l'allocatore predefinito, che usa new e delete.
Boost fornisce un pool allocator, e sarebbe più o meno così:
#include <list>
#include <queue>
// pool
#include <boost/pool/pool_alloc.hpp>
// helpful typedef's
typedef boost::fast_pool_allocator<int> BoostIntAllocator;
typedef boost::singleton_pool<boost::fast_pool_allocator_tag, sizeof(int)> BoostIntAllocatorPool;
int main(void)
{
// specify the list as the underlying container, and inside of that,
// specify fast_pool_allocator as the allocator. by default, it preallocates
// 32 elements.
std::queue<int, std::list<int, BoostIntAllocator > > q;
/* No memory allocations take place below this comment */
for (int i = 0; i < 31; ++i)
{
q.push(i);
}
/* End no allocation */
// normally, the memory used by the singleton will
// not be free'd until after the program is complete,
// but we can purge the memory manually, if desired:
BoostIntAllocatorPool::purge_memory();
};
La piscina alloca la memoria up-front, quindi non allocazione di memoria effettiva è fatto durante push()
/pop()
.
Ho utilizzato uno list
anziché uno deque
perché è più semplice. Normalmente, un deque
is superior to a list
, ma con un allocatore, le cose che davano il vantaggio di deque
, come il rendimento della cache e il costo di allocazione, non esistono più.Pertanto, un list
è molto più semplice da usare.
È inoltre possibile utilizzare un circular buffer, come ad esempio:
#include <queue>
// ring
#include <boost/circular_buffer.hpp>
int main(void)
{
// use a circular buffer as the container. no allocations take place,
// but be sure not to overflow it. this will allocate room for 32 elements.
std::queue<int, boost::circular_buffer<int> > q(boost::circular_buffer<int>(32));
/* No memory allocations take place below this comment */
for (int i = 0; i < 31; ++i)
{
q.push(i);
}
/* End no allocation */
};
Sembra che non si sa se questo è ancora un problema di prestazioni. Questo è anche un esempio molto semplice, che tipo di cose pensi di fare su questa lista? Basta spingere e pop? Diventa sempre più grande, è per lo più più piccolo, hai bisogno di un accesso indicizzato? ... – TheJacobTaylor
Non accettare la tua risposta così in fretta, alcuni di noi stanno ancora rispondendo alla tua domanda. Dagli qualche ora. – GManNickG