¿Cómo establecer el tamaño inicial de std :: vector?

130

Tengo un vector<CustomClass*>y pongo muchos elementos en el vector y necesito un acceso rápido, por lo que no uso la lista. ¿Cómo establecer el tamaño inicial del vector (por ejemplo, 20 000 lugares, para evitar copiar cuando inserto uno nuevo)?

Damir
fuente
1
Hay un constructor y dos funciones para esto en cualquier std::vectorreferencia, dependiendo de cuál se adapte mejor a sus necesidades.
Chris
1
No puede evitar copiar simplemente estableciendo el valor inicial.
juanchopanza
1
¿Evitar copias de? Almacenar punteros es bastante ligero en términos de costo de copia.
user7116
1
@Damir, ¿te referías std::vectoral título?
Robᵩ

Respuestas:

180
std::vector<CustomClass *> whatever(20000);

o:

std::vector<CustomClass *> whatever;
whatever.reserve(20000);

El primero establece el tamaño real de la matriz, es decir, lo convierte en un vector de 20000 punteros. Este último deja el vector vacío, pero reserva espacio para 20000 punteros, por lo que puede insertar (hasta) tantos sin tener que reasignarlos.

Al menos en mi experiencia, es bastante inusual que cualquiera de estos haga una gran diferencia en el rendimiento, pero puede afectar la corrección en algunas circunstancias. En particular, mientras no tenga lugar una reasignación, se garantiza que los iteradores en el vector seguirán siendo válidos, y una vez que haya establecido el tamaño / espacio reservado, tiene la garantía de que no habrá reasignaciones siempre que no lo haga ' t aumentar el tamaño más allá de eso.

Jerry Coffin
fuente
¿Cuál de estos sería más eficiente para una gran cantidad de inserciones / eliminaciones?
ctor
3
@ Loggie: Dudo que haya alguna diferencia en la eficiencia. En su mayoría, cambia la forma en que lo usa: con el primero, solo direcciona los punteros, por lo que algo así como whatever[10000] = somepointer;, donde el último requiere push_backcada puntero que agregue. Al menos si estás acostumbrado vector, este último es probablemente más simple y más natural.
Jerry Coffin
Si se conoce el tamaño del contenedor que se está copiando, ¿por qué no es más eficiente (re) dimensionar y luego copiar en lugar de push_back?
1
@Cincinnatus: Porque tiene una llamada a reserve, que asigna previamente el tamaño de la memoria. En teoría, establecer el tamaño aún podría ser minuciosamente más rápido, ya que también evita aumentar el tamaño actual cada vez que agrega un elemento. En realidad, dudo que puedas medir eso.
Jerry Coffin
1
en realidad, si está haciendo esto en una ruta rápida, y el código se llama mucho, puede hacer muchas instrucciones y ahorrar tiempo.
bayindirh
15

Debe usar la función de reserva para establecer un tamaño inicial asignado o hacerlo en el constructor inicial.

vector<CustomClass *> content(20000);

o

vector<CustomClass *> content;
...
content.reserve(20000);

Cuando reserve()elementos, vectorasignará suficiente espacio para (¿al menos?) Tantos elementos. Los elementos no existen en el vector, pero la memoria está lista para ser utilizada. Esto posiblemente se acelerará push_back()porque la memoria ya está asignada.


fuente
La asignación del tamaño también se puede proporcionar durante la construcción al pasar un argumento integral (por ejemplo std::vector<Custom Class*> content(100);)
adelbertc
@kstruct: Sí, pero puede ser menos eficiente, por una cantidad muy pequeña.