web-dev-qa-db-fra.com

Choix entre vector :: resize () et vector :: reserve ()

Je pré-alloue un peu de mémoire à ma variable membre vector. Le code ci-dessous est une partie minimale

class A {
  vector<string> t_Names;
public:
  A () : t_Names(1000) {}
};

Maintenant, à un moment donné, si t_Names.size() est égal à 1000. J'ai l'intention d'augmenter la taille de 100. Ensuite, si elle 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 en quelque sorte une estimation précise pour le t_Names. J’estime que c’est autour de 700 à 800. Toutefois, dans certaines situations (rarement), la croissance peut être supérieure à 1000.

138
iammilind

Les deux fonctions font des choses très différentes!

La méthode resize() (et transmettre un argument au constructeur équivaut à cela) insère ou supprime le nombre approprié d'éléments dans le vecteur afin de lui donner une taille donnée (le second argument est optionnel pour spécifier leur valeur). Cela affectera la size(), l'itération passera par tous ces éléments, Push_back l'insérera après eux et vous pourrez y accéder directement en utilisant le operator[].

La méthode reserve() alloue uniquement de la mémoire, mais la laisse non initialisée. Cela n'affecte que capacity(), mais size() reste 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, il n'y aura pas de réallocation, 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 souhaitez insérer 1 000 éléments et que vous souhaitez éviter quelques allocations, utilisez reserve().

EDIT: Le commentaire de Blastfurnace m'a incité à relire la question et à me rendre compte que dans votre cas, la réponse correcte est , don ' t préallouer manuellement. Continuez simplement à insérer les éléments à la fin, selon vos besoins. Le vecteur se réaffectera automatiquement selon les besoins et le fera plus plus efficacement que la méthode manuelle mentionnée. reserve() est utile uniquement lorsque vous disposez d'une estimation suffisamment précise de la taille totale dont vous aurez besoin, et dont vous aurez facilement besoin à 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 agir.

237
Jan Hudec

resize() alloue non seulement de la mémoire, mais aussi crée autant d'occurrences que la taille souhaitée que vous transmettez à resize() en tant qu'argument. Mais reserve() n'alloue que de la mémoire, il ne crée pas d'instances. C'est,

std::vector<int> v1;
v1.resize(1000); //allocation + instance creation
cout <<(v1.size() == 1000)<< endl;   //prints 1
cout <<(v1.capacity()==1000)<< endl; //prints 1

std::vector<int> v2;
v2.reserve(1000); //only allocation
cout <<(v2.size() == 1000)<< endl;   //prints 0
cout <<(v2.capacity()==1000)<< endl; //prints 1

Sortie ( démo en ligne ):

1
1
0
1

Donc, resize() peut ne pas être souhaitable, si vous ne voulez pas les objets créés par défaut. Ce sera lent aussi. En outre, si vous Push_back() nouveaux éléments, la size() du vecteur augmentera encore en allouant une nouvelle mémoire (ce qui signifie également que les éléments existants sont déplacés vers la mémoire nouvellement allouée espace). Si vous avez utilisé reserve() au début pour vous assurer que la mémoire allouée est déjà suffisante, la size() du vecteur augmentera lorsque vous Push_back(), mais il n’allouera plus de nouvelle mémoire tant que l’espace que vous avez réservé ne sera pas épuisé .

26
Nawaz

reserve lorsque vous ne souhaitez pas que les objets soient initialisés lors de la réservation. vous pouvez également préférer logiquement différencier et suivre son compte par rapport à son utilisation lors du redimensionnement. il y a donc une différence de comportement dans l'interface: le vecteur représentera le même nombre d'éléments, une fois réservé, et 100 éléments plus grands, une fois redimensionné dans votre scénario.

Y a-t-il un meilleur choix dans ce genre de scénario?

cela dépend entièrement de vos objectifs lorsque vous combattez le comportement par défaut. certaines personnes vont préférer 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.

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?

2
justin

D'après votre description, il semble que vous souhaitiez "réserver" l'espace de stockage alloué du vecteur t_Names.

Notez que resize initialise le vecteur nouvellement alloué, où reserve alloue mais ne construit pas. Par conséquent, "réserve" est beaucoup plus rapide que "redimensionner"

Vous pouvez vous référer à la documentation concernant la différence entre redimensionner et réserver

1
dip