wake-up-neo.com

Wahl zwischen vector :: resize () und vector :: reserve ()

Ich reserviere etwas Speicher für meine Member-Variable vector. Der folgende Code ist ein minimaler Teil

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

Nun, irgendwann, wenn die t_Names.size() gleich 1000 Ist. Ich beabsichtige, die Größe um 100 Zu erhöhen. Wenn es dann 1100 Erreicht, erhöhen Sie es erneut um 100 Und so weiter.

Meine Frage ist, was zwischen vector::resize() und vector::reserve() zu wählen ist. Gibt es eine bessere Wahl in dieser Art von Szenario?

Edit: Ich habe eine genaue Schätzung für t_Names. Ich schätze, dass es sich um 700 Bis 800 Handelt. In bestimmten (seltenen) Situationen kann es jedoch zu einer Zunahme von mehr als 1000 Kommen.

138
iammilind

Die beiden Funktionen machen ganz unterschiedliche Dinge!

Die resize() -Methode (und die Übergabe des Arguments an den Konstruktor entspricht dieser Methode) fügt dem Vektor eine entsprechende Anzahl von Elementen hinzu oder löscht sie, um die angegebene Größe zu erhalten (optionales zweites Argument für) Wert angeben). Dies wirkt sich auf die size() aus, die Iteration durchläuft alle diese Elemente, Push_back wird nach ihnen eingefügt und Sie können mit operator[] Direkt darauf zugreifen.

Die reserve() -Methode reserviert nur Speicher, lässt ihn jedoch nicht initialisiert. Es betrifft nur capacity(), aber size() bleibt unverändert. Es gibt keinen Wert für die Objekte, da dem Vektor nichts hinzugefügt wird. Wenn Sie dann die Elemente einfügen, erfolgt keine Neuzuweisung, da dies im Voraus erfolgt ist, dies ist jedoch der einzige Effekt.

Es kommt also darauf an, was Sie wollen. Wenn Sie ein Array mit 1000 Standardelementen möchten, verwenden Sie resize(). Verwenden Sie reserve(), wenn Sie ein Array möchten, in das 1000 Elemente eingefügt werden sollen, und mehrere Zuordnungen vermeiden möchten.

EDIT: Blastfurnace's Kommentar veranlasste mich, die Frage erneut zu lesen und festzustellen, dass in Ihrem Fall die richtige Antwort don 'ist. t manuell vorbelegen . Fügen Sie die Elemente einfach nach Bedarf am Ende ein. Der Vektor ordnet sich bei Bedarf automatisch neu zu und erledigt dies mehr effizienter als auf die angegebene manuelle Weise. Der einzige Fall, in dem reserve() Sinn macht, ist, wenn Sie eine einigermaßen genaue Schätzung der Gesamtgröße haben, die Sie im Voraus leicht verfügbar haben müssen.

EDIT2: Bearbeitung der Anzeigenfrage: Wenn Sie eine anfängliche Schätzung haben, dann reserve() diese Schätzung. Wenn es nicht genug ist, lassen Sie den Vektor einfach das Richtige tun.

237
Jan Hudec

resize() reserviert nicht nur Speicher, sondern erstellt so viele Instanzen wie die gewünschte Größe, an die Sie übergeben resize() als Argument. Aber reserve() reserviert nur Speicher, erstellt keine Instanzen. Das ist,

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

Ausgabe ( Online-Demo ):

1
1
0
1

Daher ist resize() möglicherweise nicht wünschenswert, wenn Sie die standardmäßig erstellten Objekte nicht verwenden möchten. Es wird auch langsam sein. Außerdem wird, wenn Sie Push_back() neue Elemente hinzufügen, die size() des Vektors weiter erhöht , indem Sie neuen Speicher zuweisen (was auch bedeutet) Verschieben der vorhandenen Elemente in den neu zugewiesenen Speicherplatz). Wenn Sie reserve() zu Beginn verwendet haben, um sicherzustellen, dass bereits genügend Speicher zugewiesen ist, erhöht sich die size() des Vektors, wenn Sie Push_back() dazu, , aber es wird kein neuer Speicher zugewiesen, bis der für ihn reservierte Speicherplatz erschöpft ist .

26
Nawaz

reservieren, wenn Sie nicht möchten, dass die Objekte bei der Reservierung initialisiert werden. Außerdem können Sie es vorziehen, die Anzahl logisch zu unterscheiden und zu verfolgen, wenn Sie die Größe ändern. Daher gibt es einen Unterschied im Verhalten der Benutzeroberfläche: Der Vektor stellt bei der Reservierung die gleiche Anzahl von Elementen dar und ist um 100 Elemente größer, wenn die Größe in Ihrem Szenario geändert wird.

Gibt es eine bessere Wahl in dieser Art von Szenario?

es hängt ganz von Ihren Zielen ab, wenn Sie das Standardverhalten bekämpfen. Einige Leute bevorzugen angepasste Allokatoren - aber wir brauchen wirklich eine bessere Vorstellung davon, was Sie in Ihrem Programm zu lösen versuchen, um Sie gut zu beraten.

fwiw, viele Vektorimplementierungen verdoppeln einfach die Anzahl der zugewiesenen Elemente, wenn sie wachsen müssen. Versuchen Sie, die Größe der Spitzenzuweisungen zu minimieren, oder möchten Sie genügend Speicherplatz für ein Programm ohne Sperren oder etwas anderes reservieren?

2
justin

Aus Ihrer Beschreibung geht hervor, dass Sie den zugewiesenen Speicherplatz des Vektors t_Names "reservieren" möchten.

Beachten Sie, dass resize den neu zugewiesenen Vektor initialisiert, wobei reserve nur zuweist, aber nicht konstruiert. Daher ist 'reserve' viel schneller als 'resize'

Bezüglich des Unterschieds von Größenänderung und Reserve können Sie sich auf die Dokumentation beziehen

1
dip