Estoy preasignando algo de memoria a mi vector
variable miembro. El siguiente código es parte mínima
class A {
vector<string> t_Names;
public:
A () : t_Names(1000) {}
};
Ahora en algún momento, si el t_Names.size()
igual 1000
. Tengo la intención de aumentar el tamaño en 100
. Luego, si llega 1100
, nuevamente aumenta en 100
y así sucesivamente.
Mi pregunta es, qué elegir entre vector::resize()
y vector::reserve()
. ¿Hay alguna mejor opción en este tipo de escenario?
Editar : Tengo una especie de estimación precisa para el t_Names
. Calculo que sea en torno 700
a 800
. Sin embargo, en ciertas situaciones (rara vez), puede crecer más que 1000
.
std::vector
.Respuestas:
¡Las dos funciones hacen cosas muy diferentes!
El
resize()
método (y pasar el argumento al constructor es equivalente a eso) insertará o eliminará el número apropiado de elementos al vector para darle un tamaño dado (tiene un segundo argumento opcional para especificar su valor). Afectará asize()
, la iteración repasará todos esos elementos, push_back se insertará después de ellos y puede acceder directamente a ellos usandooperator[]
.El
reserve()
método solo asigna memoria, pero la deja sin inicializar. Solo afectacapacity()
, pero nosize()
cambiará. No hay valor para los objetos, porque no se agrega nada al vector. Si luego inserta los elementos, no ocurrirá ninguna reasignación, porque se realizó de antemano, pero ese es el único efecto.Entonces depende de lo que quieras. Si desea una matriz de 1000 elementos predeterminados, use
resize()
. Si desea una matriz en la que espera insertar 1000 elementos y desea evitar un par de asignaciones, usereserve()
.EDITAR: El comentario de Blastfurnace me hizo leer la pregunta nuevamente y darme cuenta de que, en su caso, la respuesta correcta es no preasignar manualmente. Simplemente siga insertando los elementos al final según lo necesite. El vector se reasignará automáticamente según sea necesario y lo hará de manera más eficiente que la forma manual mencionada. El único caso en el que
reserve()
tiene sentido es cuando tiene una estimación razonablemente precisa del tamaño total que necesitará fácilmente disponible por adelantado.EDIT2: Edición de pregunta publicitaria: si tiene una estimación inicial, entonces
reserve()
esa estimación. Si resulta que no es suficiente, simplemente deja que el vector haga lo suyo.fuente
vector
.x.reserve(x.size() + newdata); vector<int>::iterator special_element = get_special_element(x); for (int i = 0; i < newdata; ++i) { if some_function(i, special_element) x.push_back(i); }
es bastante robusto en lo que respecta a reservar el espacio. No tengo idea de cuántos elementos se agregarán realmente, pero tengo un límite superior. Por supuesto, cuando tenga dudas, con los vectores solo puede usar índices en lugar de iteradores, la diferencia generalmente es insignificante.size()
. "El método reserve () solo asigna memoria" - puede o no asignar memoria dependiendo de sicapacity()
ya es suficiente, también puede necesitar mover elementos y desasignar su memoria original. "quiere evitar un par de asignaciones" y copias, etc.resize()
no solo asigna memoria, sino que también crea tantas instancias como el tamaño deseado que usted pasaresize()
como argumento. Peroreserve()
solo asigna memoria, no crea instancias. Es decir,Salida ( demostración en línea ):
Por
resize()
lo tanto, puede no ser deseable, si no desea los objetos creados por defecto. Será lento también. Además, si lepush_back()
agrega nuevos elementos, lasize()
del vector aumentará aún más asignando nueva memoria (lo que también significa mover los elementos existentes al espacio de memoria recién asignado). Si lo ha utilizadoreserve()
al principio para asegurarse de que ya hay suficiente memoria asignada, lasize()
del vector aumentará cuando lo hagapush_back()
, pero no asignará nueva memoria nuevamente hasta que se agote el espacio que le reservó .fuente
reserve(N)
, podemos usarlo sinoperator []
causar daño. correcto?reserve
, la especificación solo requiere que asigne al menos esa cantidad, por lo que algunas implementaciones pueden redondearse a algún límite y, por lo tanto, mostrar una capacidad superior a 1000.v.size()
. Tenga en cuenta quereserve(N)
no cambiasize()
de vector.Según su descripción, parece que desea "reservar" el espacio de almacenamiento asignado del vector t_Names.
Tenga en cuenta que
resize
inicializa el vector recién asignado dondereserve
solo asigna pero no construye. Por lo tanto, 'reservar' es mucho más rápido que 'cambiar tamaño'Puede consultar la documentación sobre la diferencia de cambio de tamaño y reserva
fuente
reserve cuando no desee que los objetos se inicialicen cuando esté reservado. Además, es posible que prefiera diferenciar lógicamente y realizar un seguimiento de su recuento frente a su recuento de uso cuando cambie el tamaño. por lo tanto, existe una diferencia de comportamiento en la interfaz: el vector representará la misma cantidad de elementos cuando esté reservado, y será 100 elementos más grande cuando se redimensione en su escenario.
depende completamente de tus objetivos cuando luches contra el comportamiento predeterminado. algunas personas favorecerán asignadores personalizados, pero realmente necesitamos una mejor idea de lo que está intentando resolver en su programa para asesorarlo bien.
fwiw, muchas implementaciones de vectores simplemente duplicarán el recuento de elementos asignados cuando deben crecer: ¿está tratando de minimizar los tamaños máximos de asignación o está tratando de reservar suficiente espacio para algún programa sin bloqueo u otra cosa?
fuente
operator[]
ni nada.