2012-09-14 16 views
6

sé que deque es más eficiente que el vector cuando inserciones están en el frente o al final del vector y es mejor si tenemos que hacer la aritmética de punteros. ¿Pero cuál usar cuando tenemos que realizar inserciones en el medio? y por qué.?vector vs inserción deque en medio

+3

Deque puede no ser más eficiente, especialmente si solo hay una pequeña cantidad de elementos. –

+0

Para colecciones relativamente pequeñas de objetos baratos para copiar, 'vector' late el resto de los contenedores, independientemente de las operaciones. (He medido 'vector ' contra 'deque ' para un FIFO con un máximo de 12 caracteres, y aunque 'deque' está optimizado para esta utilización,' vector' fue significativamente más rápido en la máquina que probé) –

Respuesta

10

Se podría pensar que un deque tendría la ventaja, porque almacena los datos divididos en bloques. Sin embargo, implementar operator[] en tiempo constante requiere que todos esos bloques tengan el mismo tamaño. Insertar o eliminar un elemento en el medio todavía requiere desplazar todos los valores en un lado u otro, al igual que vector. Dado que el vector es más simple y tiene una mejor ubicación para el almacenamiento en caché, debería salir adelante.

0

Deque todavía sería más eficiente, ya que no tiene que mover la mitad de la matriz cada vez que inserta un elemento.

Por supuesto, esto solo importará si considera un gran número de elementos, e incluso si es recomendable ejecutar un punto de referencia y ver cuál funciona mejor en su caso particular. Recuerde que premature optimization is the root of all evil.

+0

A menos que esté insertando en uno de los extremos, 'deque' requerirá el desplazamiento de algunos de los elementos: ya sea antes de la inserción o después de la inserción. –

+0

@JamesKanze cierto, pero por lo general solo se tendrá que mover un número limitado de ellos. Estoy bastante seguro de que no será la mitad de todos los elementos como en el caso del vector. – Qnan

1

std::dequepodría realizar mejor para recipientes grandes, ya que se implementa típicamente como una secuencia enlazada de bloques de datos contiguos, en oposición al bloque único usado en un std::vector. Por lo tanto, una inserción en el medio daría como resultado que se copiarían menos datos de un lugar a otro, y potencialmente menores reasignaciones.

Por supuesto, ya sea que importe o no, depende del tamaño de los contenedores y del costo de copiar los elementos almacenados. Con la semántica del movimiento de C++ 11, el costo de este último es menos importante. Pero al final, la única forma de saber es perfilar con una aplicación realista.

+0

Estoy de acuerdo, pero debe tenerse en cuenta que los bloques de datos contiguos en el párrafo 1 son lógicos, no físicos. El OP debería investigar el diseño físico más para comprender completamente las ramificaciones de las inserciones medias – WhozCraig

+0

Como señalé en mi comentario a la respuesta de Doug T., esto es falso. Si está insertando cerca del principio, 'deque' _could_ elige desplazar solo los elementos antes de la inserción, por lo tanto, desplazando menos de' vector'. No sé si alguna implementación realmente hace esto, sin embargo, y en cualquier caso, debe desplazar _todos los elementos en un lado de la inserción, ya sea antes o después. –

+0

@JamesKanze quizás expresé mi respuesta mal. No estoy en desacuerdo con lo que dices. Mi punto es que * todos * los elementos para mover tienen más probabilidades de ser un número más pequeño para un "deque" que para un "vector". – juanchopanza

3

Criterios de selección con la biblioteca contenedores estándar es, se selecciona un contenedor dependiendo de:

  1. tipo de datos que desea almacenar &
  2. El tipo de operación que desea realizar en los datos.

Si desea realizar una gran cantidad de inserciones en el medio, es mucho mejor que utilice un std::list.

Si la elección es sólo entre un std::deque y std::vector entonces hay una serie de factores a tener en cuenta:

  • Por lo general, hay una más indirecta en caso de doble cola para acceder a los elementos, por lo que el elemento acceso y el movimiento iterativo de deques suele ser un poco más lento.
  • En sistemas que tienen limitaciones de tamaño para bloques de memoria, un deque puede contener más elementos porque usa más de un bloque de memoria. Por lo tanto, max_size() podría ser más grande para deques.
  • Deques no proporcionan soporte para controlar la capacidad y el momento de la reasignación. En en particular, cualquier inserción o eliminación de elementos que no sean al principio o al final invalida todos los punteros, referencias e iteradores que hacen referencia a los elementos del deque. Sin embargo, la reasignación puede funcionar mejor que para los vectores, porque según su estructura interna típica , los deques no tienen que copiar todos los elementos en la reasignación.
  • bloques de memoria podría obtener liberados cuando ya no se utilizan, por lo que el tamaño de la memoria de un deque podría reducir el tamaño (esto no es una condición impuesta por la norma, pero la mayoría de las implementaciones de hacer)
+2

Esto no es tan evidente como podría parecer. En las arquitecturas modernas, 'std :: list' es muy ineficiente, en general, debido a su ubicación pobre, y si el contenido es barato de copiar, puede ser más rápido insertarlo en el medio de un' vector', a pesar de la copia . –

+0

Además, la estructura interna de 'deque' sí requiere copiar todos los elementos en al menos un lado de la inserción, si la inserción no está al final. (De manera más general, se puede decir que 'vector' requiere desplazar todos los elementos después de la inserción, y' deque' requiere cambiar todos los elementos antes o todos los elementos). –

Cuestiones relacionadas