Ich ordne meiner vector
Mitgliedsvariablen vorab etwas Speicher zu . Der folgende Code ist ein minimaler Teil
class A {
vector<string> t_Names;
public:
A () : t_Names(1000) {}
};
Jetzt irgendwann, wenn das t_Names.size()
gleich ist 1000
. Ich beabsichtige, die Größe um zu erhöhen 100
. Wenn es dann erreicht 1100
, erhöhen Sie erneut um 100
und so weiter.
Meine Frage ist, was ich zwischen vector::resize()
und wählen soll vector::reserve()
. Gibt es eine bessere Wahl für ein solches Szenario?
Edit : Ich habe eine Art genaue Schätzung für die t_Names
. Ich schätze , es zu sein um 700
zu 800
. In bestimmten (seltenen) Situationen kann es jedoch mehr als wachsen 1000
.
std::vector
.Antworten:
Die beiden Funktionen machen sehr unterschiedliche Dinge!
Das
resize()
Methode (und die Übergabe des Arguments an den Konstruktor entspricht dieser) fügt eine entsprechende Anzahl von Elementen in den Vektor ein oder löscht ihn, um ihm eine bestimmte Größe zu geben (optional gibt es ein zweites Argument, um ihren Wert anzugeben).size()
Dies wirkt sich auf die aus , die Iteration durchläuft alle diese Elemente, push_back wird nach ihnen eingefügt und Sie können direkt mit auf die Elemente zugreifenoperator[]
.Das
reserve()
Methode weist nur Speicher zu, lässt ihn jedoch nicht initialisiert. Es wirkt sich nur auscapacity()
,size()
bleibt aber 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()
. Wenn Sie ein Array möchten, in das Sie voraussichtlich 1000 Elemente einfügen und einige Zuordnungen vermeiden möchten, verwenden Siereserve()
.BEARBEITEN : Durch den Kommentar von Blastfurnace habe ich die Frage erneut gelesen und festgestellt, dass in Ihrem Fall die richtige Antwort nicht manuell vorab zugewiesen wird. Fügen Sie einfach die Elemente am Ende nach Bedarf ein. Der Vektor wird bei Bedarf automatisch neu zugewiesen und führt mehr aus effizienter als die manuelle Art und Weise erwähnt. Der einzige Fall, in dem dies
reserve()
sinnvoll ist, ist, wenn Sie eine einigermaßen genaue Schätzung der Gesamtgröße haben, die Sie im Voraus benötigen.EDIT2: Anzeigenfrage bearbeiten: Wenn Sie eine anfängliche Schätzung haben, dann
reserve()
diese Schätzung. Wenn sich herausstellt, dass dies nicht ausreicht, lassen Sie den Vektor einfach das tun.quelle
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); }
ist ziemlich robust, was die Reservierung des Platzes betrifft. Ich habe keine Ahnung, wie viele Elemente tatsächlich hinzugefügt werden, aber ich habe eine Obergrenze. Im Zweifelsfall ist der Unterschied bei Vektoren, bei denen Sie nur Indizes anstelle von Iteratoren verwenden können, normalerweise vernachlässigbar.size()
. "Die Reserve () -Methode weist nur Speicher zu" - sie kann Speicher zuweisen oder nicht, je nachdem, obcapacity()
weist bereits ausreicht. Möglicherweise müssen auch Elemente verschoben und der ursprüngliche Speicher freigegeben werden. "Ich möchte ein paar Zuweisungen vermeiden" und Kopien usw.resize()
reserviert nicht nur Speicher, sondern erstellt auch so viele Instanzen wie die gewünschte Größe, an die Sieresize()
als Argument übergeben. Ordnet aberreserve()
nur Speicher zu, es werden keine Instanzen erstellt. Das ist,Ausgabe ( Online-Demo ):
Dies ist
resize()
möglicherweise nicht wünschenswert, wenn Sie die standardmäßig erstellten Objekte nicht möchten. Es wird auch langsam sein. Wenn Siepush_back()
neue Elemente hinzufügen,size()
erhöht sich außerdem der Vektor weiter, indem neuer Speicher zugewiesen wird (was auch bedeutet, dass die vorhandenen Elemente in den neu zugewiesenen Speicherbereich verschoben werden). Wenn Siereserve()
zu Beginn verwendet haben, um sicherzustellen, dass bereits genügend Speicher zugewiesen ist, wird diesize()
erhöht sich der Vektor, wenn Sie daraufpush_back()
zugreifen. Er weist jedoch erst dann neuen Speicher zu, wenn der für Sie .quelle
reserve(N)
können wiroperator []
harmlos verwenden. richtig ?reserve
, erfordert die Spezifikation nur, dass mindestens so viel zugewiesen wird, sodass einige Implementierungen bis zu einer bestimmten Grenze aufrunden und somit eine höhere Kapazität als 1000 aufweisen können.v.size()
. Beachten Sie, dassreserve(N)
sichsize()
der Vektor nicht ändert .Aus Ihrer Beschreibung geht hervor, dass Sie den zugewiesenen Speicherplatz des Vektors t_Names "reservieren" möchten.
Beachten Sie, dass
resize
der neu zugewiesene Vektor initialisiert wird, derreserve
nur zugewiesen, aber nicht erstellt wird. Daher ist "Reserve" viel schneller als "Größe ändern"Informationen zum Unterschied zwischen Größe und Reserve finden Sie in der Dokumentation
quelle
reservieren, wenn die Objekte bei der Reservierung nicht initialisiert werden sollen. Möglicherweise möchten Sie auch die Anzahl der Verwendungszwecke logisch unterscheiden und nachverfolgen, wenn Sie die Größe ändern. Es gibt also einen Verhaltensunterschied in der Benutzeroberfläche: Der Vektor repräsentiert die gleiche Anzahl von Elementen, wenn er reserviert ist, und ist 100 Elemente größer, wenn die Größe in Ihrem Szenario geändert wird.
Es hängt ganz von Ihren Zielen ab, wenn Sie das Standardverhalten bekämpfen. Einige Leute werden maßgeschneiderte Allokatoren bevorzugen - 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 versuchen Sie, genügend Speicherplatz für ein sperrenfreies Programm oder etwas anderes zu reservieren?
quelle
operator[]
oder auf nichts zugegriffen werden kann.