Para conocer la diferencia hay que saber cómo deque
se implementa en general. La memoria se asigna en bloques de igual tamaño y están encadenados (como una matriz o posiblemente un vector).
Entonces, para encontrar el enésimo elemento, busque el bloque apropiado y luego acceda al elemento dentro de él. Este es un tiempo constante, porque siempre son exactamente 2 búsquedas, pero aún es más que el vector.
vector
también funciona bien con las API que desean un búfer contiguo porque son API de C o son más versátiles para poder tomar un puntero y una longitud. (Por lo tanto, puede tener un vector debajo o una matriz regular y llamar a la API desde su bloque de memoria).
Donde deque
tiene sus mayores ventajas son:
- Al aumentar o reducir la colección desde cualquier extremo
- Cuando se trata de colecciones de gran tamaño.
- Cuando se trata de bools y realmente desea bools en lugar de bitset.
El segundo de estos es menos conocido, pero para tamaños de colección muy grandes:
- El costo de la reasignación es grande
- La sobrecarga de tener que encontrar un bloque de memoria contiguo es restrictiva, por lo que puede quedarse sin memoria más rápido.
Cuando estaba tratando con colecciones grandes en el pasado y me mudé de un modelo contiguo a un modelo de bloque, pudimos almacenar una colección aproximadamente 5 veces más grande antes de que nos quedáramos sin memoria en un sistema de 32 bits. Esto se debe en parte a que, al reasignar, en realidad necesitaba almacenar el bloque antiguo y el nuevo antes de copiar los elementos.
Habiendo dicho todo esto, puede tener problemas con los std::deque
sistemas que utilizan una asignación de memoria "optimista". Si bien sus intentos de solicitar un tamaño de búfer grande para una reasignación de a vector
probablemente serán rechazados en algún momento con a bad_alloc
, es probable que la naturaleza optimista del asignador siempre otorgue la solicitud del búfer más pequeño solicitado por a deque
y que probablemente cause el sistema operativo para matar un proceso para intentar adquirir algo de memoria. Cualquiera que elija puede que no sea demasiado agradable.
Las soluciones en tal caso son establecer indicadores a nivel del sistema para anular la asignación optimista (no siempre es factible) o administrar la memoria de manera algo más manual, por ejemplo, usando su propio asignador que verifica el uso de memoria o similar. Obviamente no es ideal. (Lo que puede responder a su pregunta de preferir el vector ...)
std::deque
tiene un tamaño de bloque máximo muy pequeño (~ 16 bytes, si recuerdo correctamente; tal vez 32) y, como tal, no funciona muy bien para aplicaciones realistas. Adeque<T>
dondesizeof(T) > 8
(o 16? Es un número pequeño) tiene aproximadamente las mismas características de rendimiento que avector<T*>
, donde cada elemento se asigna dinámicamente. Otras implementaciones tienen diferentes tamaños de bloque máximos, por lo que escribir código que tenga relativamente las mismas características de rendimiento en diferentes plataformas es difícildeque
.