Per conoscere la differenza si dovrebbe sapere come deque
viene generalmente implementato. La memoria è allocata in blocchi di dimensioni uguali e sono concatenati insieme (come un array o eventualmente un vettore).
Quindi, per trovare l'ennesimo elemento, trova il blocco appropriato e accedi all'elemento al suo interno. Questo è un tempo costante, perché è sempre esattamente 2 ricerche, ma è ancora più del vettore.
vector
funziona bene anche con le API che desiderano un buffer contiguo perché sono API C o sono più versatili in quanto possono prendere un puntatore e una lunghezza. (Quindi puoi avere un vettore sotto o un array normale e chiamare l'API dal tuo blocco di memoria).
Dove deque
ha i suoi maggiori vantaggi sono:
- Quando si cresce o si restringe la collezione da entrambe le estremità
- Quando hai a che fare con raccolte di dimensioni molto grandi.
- Quando si ha a che fare con bool e si desidera davvero bool piuttosto che un set di bit.
Il secondo di questi è meno conosciuto, ma per formati di raccolta molto grandi:
- Il costo della riallocazione è elevato
- Il sovraccarico di dover trovare un blocco di memoria contiguo è restrittivo, quindi puoi esaurire la memoria più velocemente.
Quando in passato avevo a che fare con raccolte di grandi dimensioni e passavo da un modello contiguo a un modello a blocchi, siamo stati in grado di archiviare una raccolta circa 5 volte più grande prima di esaurire la memoria in un sistema a 32 bit. Ciò è in parte dovuto al fatto che, durante la riallocazione, era effettivamente necessario memorizzare il vecchio blocco oltre a quello nuovo prima di copiare gli elementi.
Detto questo, potresti avere problemi con i std::deque
sistemi che utilizzano l'allocazione di memoria "ottimistica". Sebbene i suoi tentativi di richiedere una grande dimensione del buffer per una riallocazione di a vector
verranno probabilmente rifiutati ad un certo punto con a bad_alloc
, è probabile che la natura ottimistica dell'allocatore garantisca sempre la richiesta per il buffer più piccolo richiesto da a deque
e questo il sistema operativo per terminare un processo per cercare di acquisire memoria. Qualunque cosa scelga potrebbe non essere troppo piacevole.
La soluzione alternativa in questo caso consiste nell'impostare flag a livello di sistema per sovrascrivere l'allocazione ottimistica (non sempre fattibile) o gestire la memoria un po 'più manualmente, ad esempio utilizzando il proprio allocatore che controlla l'utilizzo della memoria o simili. Ovviamente non è l'ideale. (Che potrebbe rispondere alla tua domanda come preferire il vettore ...)
std::deque
ha una dimensione massima del blocco molto piccola (~ 16 byte, se ricordo bene; forse 32), e come tale non funziona molto bene per applicazioni realistiche. Adeque<T>
dovesizeof(T) > 8
(o 16? È un numero piccolo) ha circa le stesse caratteristiche di prestazione di avector<T*>
, dove ogni elemento è allocato dinamicamente. Altre implementazioni hanno dimensioni massime di blocco diverse, quindi è difficile scrivere codice che abbia relativamente le stesse caratteristiche di prestazioni su piattaforme diversedeque
.