Dado que hay una gran cantidad de respuestas, es posible que se sienta confundido, pero para resumir:
Utilice un std::queue
. La razón de esto es simple: es una estructura FIFO. Si quieres FIFO, usas un std::queue
.
Deja en claro su intención para los demás, e incluso para usted mismo. A std::list
o std::deque
no. Una lista puede insertar y eliminar en cualquier lugar, que no es lo que se supone que debe hacer una estructura FIFO, y deque
puede agregar y eliminar desde cualquier extremo, que también es algo que una estructura FIFO no puede hacer.
Es por eso que debe usar un queue
.
Ahora, preguntaste sobre el rendimiento. En primer lugar, recuerde siempre esta importante regla general: el buen código primero, el rendimiento al final.
La razón de esto es simple: las personas que se esfuerzan por el rendimiento antes de la limpieza y la elegancia casi siempre terminan en último lugar. Su código se convierte en una papilla de mierda, porque han abandonado todo lo que es bueno para realmente no sacar nada de él.
Al escribir primero un código bueno y legible, la mayoría de los problemas de rendimiento se resolverán por sí mismos. Y si más tarde descubre que su rendimiento es deficiente, ahora es fácil agregar un generador de perfiles a su código agradable y limpio y averiguar dónde está el problema.
Dicho todo esto, std::queue
es solo un adaptador. Proporciona la interfaz segura, pero utiliza un contenedor diferente en el interior. Puede elegir este contenedor subyacente y esto permite una gran flexibilidad.
Entonces, ¿qué contenedor subyacente debería usar? Lo sabemos std::list
ystd::deque
ambos proporcionan las funciones necesarias ( push_back()
, pop_front()
yfront()
), por lo que ¿cómo decidir?
Primero, comprenda que asignar (y desasignar) memoria no es algo rápido, generalmente, porque implica ir al sistema operativo y pedirle que haga algo. A list
tiene que asignar memoria cada vez que se agrega algo y desasignarlo cuando desaparece.
A deque
, por otro lado, asigna en trozos. Se asignará con menos frecuencia que a list
. Piense en ello como una lista, pero cada fragmento de memoria puede contener varios nodos. (Por supuesto, le sugiero que realmente aprenda cómo funciona ).
Entonces, con eso solo un deque
debería funcionar mejor, porque no se ocupa de la memoria con tanta frecuencia. Combinado con el hecho de que está manejando datos de tamaño constante, probablemente no tendrá que asignar después del primer paso a través de los datos, mientras que una lista se asignará y desasignará constantemente.
Una segunda cosa a comprender es el rendimiento de la caché . Salir a la RAM es lento, por lo que cuando la CPU realmente lo necesita, aprovecha al máximo este tiempo llevándose una parte de la memoria a la caché. Debido a que deque
asigna fragmentos de memoria, es probable que acceder a un elemento en este contenedor haga que la CPU recupere el resto del contenedor también. Ahora cualquier otro acceso a ladeque
será más rápido, porque los datos están en la caché.
Esto es diferente a una lista, donde los datos se asignan uno a la vez. Esto significa que los datos podrían estar esparcidos por todas partes en la memoria y el rendimiento de la caché será malo.
Entonces, considerando eso, deque
debería ser una mejor opción. Es por eso que es el contenedor predeterminado cuando se usa un queue
. Dicho todo esto, esto sigue siendo solo una suposición (muy) educada: tendrá que perfilar este código, utilizando una deque
prueba en una ylist
en la otra para saberlo con certeza.
Pero recuerde: haga que el código funcione con una interfaz limpia, luego preocúpese por el rendimiento.
John plantea la preocupación de que envolver un list
o deque
provocará una disminución del rendimiento. Una vez más, ni él ni yo podemos decirlo con certeza sin perfilarlo nosotros mismos, pero es probable que el compilador incorpore las llamadas que queue
realiza. Es decir, cuando dices queue.push()
, realmente solo diráqueue.container.push_back()
, omitiendo la llamada a la función por completo.
Una vez más, esto es solo una suposición queue
fundamentada , pero el uso de a no degradará el rendimiento, en comparación con el uso del contenedor subyacente sin procesar. Como dije antes, use el queue
, porque es limpio, fácil de usar y seguro, y si realmente se convierte en un perfil de problema y prueba.