2013-05-07 11 views
32

Ho un codice in cui di solito riempio un vettore con da 0 a 5000 elementi. So che la massima non supera mai i 5000. Invece di inizializzazione vettore più volte, vorrei fare solo una voltaC++, il modo più veloce per cancellare o cancellare un vettore

vector<struct> myvector; 
myvector.reserve(5000); 

Tuttavia, per riempire di nuovo il vettore, devo cancellare il vettore prima senza alterarne la portata. Quindi di solito chiamo myvector.clear();

Questa è un'operazione O (n). C'è qualcosa di semplice che posso fare per aumentare le prestazioni di questo o è il migliore che otterrà?

+2

Assegna agli elementi esistenti una soluzione ragionevole? –

+0

No, perché potrei avere 5000 elementi la prima volta e 3500 la volta successiva e alla fine ci sarebbero 1500 elementi vecchi ... – user788171

+0

La "distruzione" di elementi è un problema? –

risposta

38

Se la propria struct ha un distruttore non banale, è necessario chiamare tutti gli elementi del vettore indipendentemente da come viene svuotato. Se la tua struct ha solo un distruttore banale, il compilatore o l'implementazione della libreria standard può ottimizzare il processo di distruzione e darti un'operazione O (1).

+0

C'è una differenza tra * "il compilatore probabilmente ottimizzerà ..." * e * "l'implementazione può ottimizzare il costo di distanza ... "* (come @ DavidRodríguez-dribeas ha detto nella sua risposta). Quest'ultimo suona più ragionevole per me! – Nawaz

+0

@Nawaz: Suppongo che sia vero. Il mio intento era qualcosa sulla falsariga di "molti compilatori eseguono questa ottimizzazione, quindi è probabile che stiate usando uno di quei compilatori", ma posso vedere come potrebbe essere interpretato come "a volte il compilatore lo farà e a volte il compilatore non ottimizzerà questo, ma di solito lo farà ". –

+0

Penso che tu non abbia capito il mio commento. L'affermazione * "l'implementazione può ottimizzare il costo ..." * è un super set, in quanto include anche l'idea * "il compilatore probabilmente ottimizzerà" *, oltre alla possibilità del codice libreria "ottimizzato". Significa che, anche se il compilatore stesso non fa l'ottimizzazione, la libreria potrebbe essere scritta in modo da emettere il codice 'O (1)' quando 'value_type' ha un distruttore banale (che è anche ciò che voleva dire @ DavidRodríguez-dribeas, vedere i suoi commenti). – Nawaz

10

Qualsiasi cosa tu faccia per rimuovere gli elementi esistenti dal vettore deve (potenzialmente) richiamare il distruttore di ogni oggetto che viene distrutto. Pertanto, dal punto di vista del contenitore, il meglio che si possa sperare è la complessità lineare.

Questo lascia solo la domanda su che tipo di elementi memorizzi nel vettore. Se si memorizza qualcosa come int che il compilatore può sapere prima del tempo non ha alcun distruttore da invocare, è probabile che la rimozione finisca con una complessità costante.

Dubito, tuttavia, che la modifica della sintassi (ad es. clear() vs. resize() vs. erase(begin(), end())) comporterà alcuna differenza significativa. La sintassi non modifica il fatto che (in assenza di threading) l'invocazione di N destructors è un'operazione O (N).

23

Il costo di clear() dipende in gran parte da cosa sono gli oggetti memorizzati e, in particolare, se hanno un distruttore banale. Se il tipo non ha un distruttore banale, la chiamata deve distruggere tutti gli oggetti memorizzati ed è in realtà un'operazione O (n), ma non si può fare nulla di meglio.

Ora, se gli elementi memorizzati hanno distruttori banali, l'implementazione può ottimizzare il costo e clear() diventa un'operazione O (1) economica (basta reimpostare la dimensione - puntatore end).

Ricordare che per comprendere la complessità asintotica è necessario sapere di cosa parla. Nel caso di clear() rappresenta il numero di distruttori chiamati, ma se il costo (nascosto) è 0, allora l'operazione è un no-op.

+0

Puoi chiarire cosa si intende per distruttore banale? Non ho familiarità con questa terminologia. – user788171

+8

Penso che in questo contesto 'trivial destructor' sia lo stesso di' no destructor'. –

+4

@ user788171: Si consiglia di leggere [Quali sono gli aggregati e i POD e come/perché sono speciali?] (Http://stackoverflow.com/a/7189821/2070725) per capire che cosa è tutta questa roba "banale" è circa (scorrere verso il basso un po 'per raggiungere la parte "banale"). – syam

Problemi correlati