Les chances sont que ce n'est pas un problème. Deque
Allouer en morceaux de toute façon, de sorte que vous aurez probablement réaffecter seulement quelques fois. Avez-vous déterminé que cela était un goulot d'étranglement? Quoi qu'il en soit, la norme ne donne pas d'accesseur au conteneur de la file d'attente, car cela annulerait le but de l'encapsulation.
Si vous êtes vraiment inquiet, allouer la piscine. Cela signifie préallouer la mémoire à l'avance, donc quand le conteneur demande de la mémoire, il est déjà là. Je ne peux pas vraiment passer en revue les allocateurs et les parents, ce serait exagéré pour une réponse SO, mais regardez allocators on Google. Fondamentalement, vous pouvez dire à votre conteneur d'où sa mémoire. Normalement, il s'agit de l'allocateur par défaut, qui utilise new et delete.
Boost fournit un pool allocator, et ce serait quelque chose comme ceci:
#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 piscine alloue la mémoire à l'avance, donc pas d'allocation de mémoire réelle est effectuée pendant push()
/pop()
. J'ai utilisé un list
au lieu d'un deque
parce que c'est plus simple. Normalement, un deque
is superior to a list
, mais avec un allocateur, les choses qui ont donné deque
son avantage, comme les performances de cache et le coût d'allocation, n'existent plus.Par conséquent, un list
est beaucoup plus simple à utiliser.
Vous pouvez également utiliser un circular buffer, comme par exemple:
#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 */
};
On dirait que vous ne savez pas si cela est encore problème de performance. C'est aussi un exemple très simple, quel genre de choses envisagez-vous de faire à cette liste? Juste pousser et pop? Est-il toujours plus grand, est-il plus petit, avez-vous besoin d'un accès indexé? ... – TheJacobTaylor
N'acceptez pas votre réponse si vite, certains d'entre nous ne font que répondre à votre question. Donnez-lui quelques heures. – GManNickG