Come impostare la dimensione iniziale di std :: vector?


130

Ho un vector<CustomClass*>e ho inserito molti elementi nel vettore e ho bisogno di un accesso rapido, quindi non uso l'elenco. Come impostare la dimensione iniziale del vettore (ad esempio essere 20.000 posti, in modo da evitare la copia quando inserisco nuovo)?


1
C'è un costruttore e due funzioni per questo in ogni std::vectorriferimento, a seconda di quale si adatta meglio alle tue esigenze.
chris,

1
Non puoi evitare di copiare semplicemente impostando il valore iniziale.
juanchopanza,

1
Evitare copie di? La memorizzazione dei puntatori è piuttosto leggera in termini di costi da copiare.
user7116,


1
@Damir, intendevi std::vectornel titolo?
Robᵩ

Risposte:


180
std::vector<CustomClass *> whatever(20000);

o:

std::vector<CustomClass *> whatever;
whatever.reserve(20000);

Il primo imposta la dimensione effettiva dell'array, ovvero lo rende un vettore di 20000 puntatori. Quest'ultimo lascia il vettore vuoto, ma riserva spazio per 20000 puntatori, quindi è possibile inserire (fino a) molti di questi senza che sia necessario riallocare.

Almeno nella mia esperienza, è abbastanza insolito che uno di questi due faccia una grande differenza nelle prestazioni, ma in alcuni casi può influire sulla correttezza. In particolare, fino a quando non viene effettuata alcuna riallocazione, gli iteratori nel vettore sono garantiti per rimanere validi e, una volta impostate le dimensioni / lo spazio riservato, si garantisce che non ci saranno riallocazioni finché non si t aumentare le dimensioni oltre.


Quale di questi sarebbe più efficiente per un gran numero di inserzioni / eliminazioni?
ctor

3
@Loggie: dubito che ci sarebbe qualche differenza nell'efficienza. Principalmente cambia il modo in cui lo usi: con il primo, devi solo indirizzare i puntatori, quindi qualcosa di simile whatever[10000] = somepointer;, dove il secondo ti richiede di push_backogni puntatore che aggiungi. Almeno se sei abituato vector, quest'ultimo è probabilmente più semplice e naturale.
Jerry Coffin,

Se si conosce la dimensione del contenitore da cui si sta copiando, perché non è più efficiente (ri) ridimensionare e quindi copiare invece di push_back?

1
@Cincinnatus: perché ha una chiamata a reserve, che pre-alloca la dimensione della memoria. In teoria, l'impostazione della dimensione potrebbe essere ancora più veloce, poiché evita anche di aumentare la dimensione corrente ogni volta che aggiungi un articolo. In realtà, dubito che potresti misurarlo però.
Jerry Coffin,

1
in realtà, se lo stai facendo su un percorso attivo e il codice è chiamato molto, puoi fare molte istruzioni e risparmiare tempo.
bayindirh,

15

È necessario utilizzare la funzione di riserva per impostare una dimensione allocata iniziale o farlo nel costruttore iniziale.

vector<CustomClass *> content(20000);

o

vector<CustomClass *> content;
...
content.reserve(20000);

Quando si reserve()elementi, vectorverranno allocati abbastanza spazio per (almeno?) Quel numero di elementi. Gli elementi non esistono in vector, ma la memoria è pronta per essere utilizzata. Questo potrebbe quindi accelerare push_back()perché la memoria è già allocata.


Allocare la dimensione può anche essere fornito durante la costruzione passando un argomento integrale (ad esempio std::vector<Custom Class*> content(100);)
adelbertc,

@kstruct: Sì, ma può essere meno efficiente - di una quantità molto piccola.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.