Скорее всего, это не проблема. В любом случае Deque
выделяется в чанках, так что вы, вероятно, будете перераспределять только несколько раз. Вы определили, что это узкое место?
В любом случае, стандарт не предоставляет средства доступа к контейнеру `queue ', потому что это противоречит цели инкапсуляции.
Если вы действительно беспокоитесь, выделите пул. Это означает предварительное выделение памяти, поэтому, когда контейнер запрашивает память, он уже там. На самом деле я не могу перейти к распределителям и родственникам, это было бы излишним для SO-ответа, но поискать распределителей в Google .
По сути, вы можете указать контейнеру, откуда взять его память. Обычно это распределитель по умолчанию, который использует new и delete.
Boost предоставляет распределитель пула , и он будет выглядеть примерно так:
#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();
};
Пул выделяет память заранее, поэтому во время push()
/ pop()
.
фактическое выделение памяти не выполняется.
Я использовал list
вместо deque
, потому что это проще. Обычно deque
превосходит list
, но с распределителем, вещи, которые дали deque
такое преимущество, как производительность кэша и стоимость выделения, больше не существуют. Поэтому list
гораздо проще в использовании.
Вы также можете использовать кольцевой буфер , например:
#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 */
};