143 votes

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

Je préaffecte de la mémoire à mon a vector variable membre. Le code ci-dessous est la partie minimale

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

Maintenant, à un moment donné, si le t_Names.size() est égal à 1000 . J'ai l'intention d'augmenter la taille de 100 . Ensuite, s'il atteint 1100 , augmentent encore de 100 et ainsi de suite.

Ma question est la suivante : que choisir entre vector::resize() y vector::reserve() . Y a-t-il un meilleur choix dans ce genre de scénario ?

Modifier : J'ai une sorte d'estimation précise pour le t_Names . Je l'estime à environ 700 a 800 . Cependant, en certains (rarement), il peut se développer plus que 1000 .

247voto

Jan Hudec Points 27417

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

El resize() (et passer l'argument au constructeur est équivalent à cela) insérera ou supprimera le nombre approprié d'éléments dans le vecteur pour lui donner une taille donnée (il a un second argument optionnel pour spécifier leur valeur). Elle affectera le size() l'itération passera en revue tous ces éléments, le push_back les insérera après et vous pourrez y accéder directement en utilisant la balise operator[] .

El reserve() alloue seulement de la mémoire, mais la laisse non initialisée. Elle n'affecte que capacity() mais size() sera 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 elle a été faite à 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 vous attendez à insérer 1000 éléments et que vous voulez éviter quelques allocations, utilisez reserve() .

EDIT : Le commentaire de Blastfurnace m'a fait relire la question et je me suis rendu compte que, dans votre cas, la réponse correcte est ne pas préallouer manuellement. Continuez à insérer les éléments à la fin selon vos besoins. Le vecteur réallouera automatiquement les éléments selon les besoins et le fera plus efficacement que la méthode manuelle mentionnée. Le seul cas où reserve() est utile lorsque vous disposez à l'avance d'une estimation raisonnablement précise de la taille totale dont vous aurez besoin.

EDIT2 : Modification de la question de l'annonce : Si vous avez une estimation initiale, alors reserve() cette estimation. S'il s'avère que ce n'est pas suffisant, laissez le vecteur faire son travail.

27voto

Nawaz Points 148870

resize() non seulement alloue de la mémoire, il a également crée autant d'instances que l' souhaité taille qui vous passent resize() comme argument. Mais reserve() seulement alloue de la mémoire, il n'est pas de créer des instances. Qui 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

De sortie (démo en ligne):

1
1
0
1

Donc, resize() peut ne pas être souhaitable, si vous ne voulez pas la valeur par défaut des objets créés. Il sera lent. En outre, si vous push_back() de nouveaux éléments, l' size() du vecteur augmenter encore par l'attribution de nouvelles de la mémoire (ce qui signifie également déplacer les éléments existants de la nouvellement alloué de l'espace mémoire). Si vous avez utilisé reserve() au début pour s'assurer qu'il existe déjà suffisamment de mémoire allouée, l' size() du vecteur augmenter lorsque vous push_back() , mais il ne sera pas à allouer la mémoire nouveau à nouveau jusqu'à ce qu'il ne manque de l'espace qui vous est réservé.

2voto

dip Points 475

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

Notez que resize initialiser le vecteur nouvellement alloué où reserve se contente d'allouer 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 de redimensionner y réserve

2voto

justin Points 72871

Réserve lorsque vous ne voulez pas que les objets soient initialisés lorsqu'ils sont réservés. de plus, vous pouvez préférer différencier et suivre logiquement son compte par rapport à son utilisation 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 est 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 favoriseront les allocateurs personnalisés -- mais nous avons vraiment besoin d'une meilleure idée de ce que vous tentez de résoudre dans votre programme pour bien vous conseiller.

En fait, de nombreuses implémentations de vecteurs doublent simplement le nombre d'éléments alloués lorsqu'ils doivent croître - essayez-vous de minimiser les tailles d'allocation maximales ou essayez-vous de réserver suffisamment d'espace pour un programme sans verrou ou autre chose ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X