Je pré-alloue de la mémoire à ma vector
variable membre. Le code ci-dessous est une partie minimale
class A {
vector<string> t_Names;
public:
A () : t_Names(1000) {}
};
Maintenant, à un moment donné, si les t_Names.size()
égaux 1000
. J'ai l'intention d'augmenter la taille de 100
. Ensuite, s'il atteint 1100
, augmentez à nouveau de 100
et ainsi de suite.
Ma question est, que choisir entre vector::resize()
et vector::reserve()
. Y a-t-il un meilleur choix dans ce genre de scénario?
Edit : j'ai une sorte d'estimation précise pour le t_Names
. J'estime que c'est autour 700
de 800
. Cependant, dans certaines situations (rarement), il peut augmenter plus de 1000
.
std::vector
.Réponses:
Les deux fonctions font des choses très différentes!
La
resize()
méthode (et passer l'argument au constructeur équivaut à cela) insérera ou supprimera le nombre approprié d'éléments dans le vecteur pour lui donner une taille donnée (elle a un deuxième argument facultatif pour spécifier leur valeur). Cela affectera lesize()
, l'itération passera sur tous ces éléments, push_back s'insérera après eux et vous pourrez y accéder directement en utilisant leoperator[]
.La
reserve()
méthode alloue uniquement de la mémoire, mais la laisse non initialisée. Cela n'affecte quecapacity()
, maissize()
restera inchangé. Il n'y a pas de valeur pour les objets, car rien n'est ajouté au vecteur. Si vous insérez ensuite les éléments, aucune réallocation ne se produira, car cela a été fait à l'avance, mais c'est le seul effet.Cela dépend donc de ce que vous voulez. Si vous voulez un tableau de 1000 éléments par défaut, utilisez
resize()
. Si vous voulez un tableau dans lequel vous prévoyez d'insérer 1000 éléments et que vous voulez éviter quelques allocations, utilisezreserve()
.EDIT: Le commentaire de Blastfurnace m'a fait relire la question et me rendre compte que dans votre cas, la bonne réponse est de ne pas préallouer manuellement. Continuez simplement à insérer les éléments à la fin selon vos besoins. Le vecteur se réallouera automatiquement si nécessaire et le fera plus efficacement que la méthode manuelle mentionnée. Le seul cas où
reserve()
cela a du sens est lorsque vous avez une estimation raisonnablement précise de la taille totale dont vous aurez besoin facilement disponible à l'avance.EDIT2: Modification de la question de l'annonce: si vous avez une estimation initiale, alors
reserve()
cette estimation. Si cela ne suffit pas, laissez simplement le vecteur faire son travail.la source
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); }
est assez robuste en ce qui concerne la réservation de l'espace. Je n'ai aucune idée du nombre d'éléments qui seront réellement ajoutés, mais j'ai une limite supérieure. Bien sûr, en cas de doute, avec des vecteurs, vous pouvez simplement utiliser des index au lieu d'itérateurs, la différence est généralement négligeable.size()
. «La méthode reserve () n'alloue que de la mémoire» - elle peut allouer ou non de la mémoire selon qu'ellecapacity()
est déjà suffisante, elle peut aussi avoir besoin de déplacer des éléments et de désallouer leur mémoire d'origine. "veux éviter quelques allocations" et des copies, etc.resize()
non seulement alloue de la mémoire, il crée également autant d'instances que la taille souhaitée que vous passezresize()
en argument. Maisreserve()
n'alloue que de la mémoire, il ne crée pas d'instances. C'est,Sortie ( démo en ligne ):
Cela
resize()
n'est peut-être pas souhaitable si vous ne voulez pas les objets créés par défaut. Ce sera aussi lent. En outre, si vous ypush_back()
ajoutez de nouveaux éléments, la valeursize()
du vecteur augmentera encore en allouant une nouvelle mémoire (ce qui signifie également déplacer les éléments existants vers l'espace mémoire nouvellement alloué). Si vous avez utiliséreserve()
au début pour vous assurer qu'il y a déjà assez de mémoire allouée, la valeursize()
du vecteur augmentera lorsque vouspush_back()
y arriverez , mais elle n'allouera pas de nouvelle mémoire tant qu'elle n'aura pas épuisé l'espace que vous lui avez réservé .la source
reserve(N)
, nous pouvons utiliseroperator []
sans danger. correct ?reserve
, la spécification exige seulement qu'elle alloue au moins autant, de sorte que certaines implémentations peuvent arrondir à une certaine limite et afficher ainsi une capacité supérieure à 1000.v.size()
. Notez quereserve(N)
cela ne change passize()
de vecteur.D'après votre description, il semble que vous vouliez "réserver" l'espace de stockage alloué du vecteur t_Names.
Notez que
resize
initialiser le vecteur nouvellement alloué oùreserve
alloue simplement mais ne construit pas. Par conséquent, «réserver» est beaucoup plus rapide que «redimensionner»Vous pouvez vous référer à la documentation concernant la différence de redimensionnement et de réserve
la source
réserver lorsque vous ne souhaitez pas que les objets soient initialisés lors de la réservation. Vous pouvez également préférer différencier et suivre logiquement son nombre par rapport à son nombre d’utilisations lorsque vous redimensionnez. il y a donc une différence de comportement dans l'interface - le vecteur représentera le même nombre d'éléments lorsqu'il est réservé, et sera 100 éléments plus grand lorsqu'il sera redimensionné dans votre scénario.
cela dépend entièrement de vos objectifs lorsque vous combattez le comportement par défaut. certaines personnes privilégieront les allocateurs personnalisés - mais nous avons vraiment besoin d'une meilleure idée de ce que vous essayez de résoudre dans votre programme pour bien vous conseiller.
fwiw, de nombreuses implémentations vectorielles doubleront simplement le nombre d'éléments alloués lorsqu'elles doivent croître - essayez-vous de minimiser les tailles d'allocation de pointe ou essayez-vous de réserver suffisamment d'espace pour un programme sans verrouillage ou autre?
la source
operator[]
ou quoi que ce soit.