Usando array o std :: vectors in C ++, qual è il gap prestazionale?


208

Nel nostro corso C ++ suggeriscono di non usare più le matrici C ++ su nuovi progetti. Per quanto ne so, lo stesso Stroustroup suggerisce di non usare le matrici. Ma ci sono differenze significative nelle prestazioni?


2
Perché pensi che ci sia un gap prestazionale.
Martin York,

99
Perché di solito con una migliore funzionalità si ottengono prestazioni peggiori.
Tunnuz,

19
Concordo sull'ottimizzazione precoce ma la scelta del metodo di archiviazione migliore in anticipo ha molto senso. Spesso nel mondo reale il codice deve essere spedito e il prodotto successivo sviluppato e la fase di ottimizzazione non ha mai luogo.
Formica

132
vorrei che la gente smettesse di urlare "ottimizzazione prematura!" ogni volta che qualcuno fa una semplice domanda relativa alla performance! rispondi alla domanda e non dare semplicemente per scontato che le persone stiano facendo qualcosa prematuramente.
d7samurai,

4
@ d7samaurai: d'accordo, devo ancora vedere qualcuno provare ad usareint main(int argc, const std::vector<string>& argv)
Mark K Cowan

Risposte:


189

L'uso di array C ++ con new(ovvero l'utilizzo di array dinamici) dovrebbe essere evitato. C'è il problema che devi tenere traccia delle dimensioni e devi eliminarle manualmente ed eseguire tutti i tipi di pulizie.

L'uso di array nello stack è anche sconsigliato perché non si ha il controllo dell'intervallo e il passaggio dell'array perderà qualsiasi informazione sulla sua dimensione (conversione dell'array in puntatore). In boost::arrayquesto caso dovresti usare , che avvolge un array C ++ in una piccola classe e fornisce una sizefunzione e iteratori per iterare su di esso.

Ora le matrici std :: vector vs. native C ++ (prese da Internet):

// Comparison of assembly code generated for basic indexing, dereferencing, 
// and increment operations on vectors and arrays/pointers.

// Assembly code was generated by gcc 4.1.0 invoked with  g++ -O3 -S  on a 
// x86_64-suse-linux machine.

#include <vector>

struct S
{
  int padding;

  std::vector<int> v;
  int * p;
  std::vector<int>::iterator i;
};

int pointer_index (S & s) { return s.p[3]; }
  // movq    32(%rdi), %rax
  // movl    12(%rax), %eax
  // ret

int vector_index (S & s) { return s.v[3]; }
  // movq    8(%rdi), %rax
  // movl    12(%rax), %eax
  // ret

// Conclusion: Indexing a vector is the same damn thing as indexing a pointer.

int pointer_deref (S & s) { return *s.p; }
  // movq    32(%rdi), %rax
  // movl    (%rax), %eax
  // ret

int iterator_deref (S & s) { return *s.i; }
  // movq    40(%rdi), %rax
  // movl    (%rax), %eax
  // ret

// Conclusion: Dereferencing a vector iterator is the same damn thing 
// as dereferencing a pointer.

void pointer_increment (S & s) { ++s.p; }
  // addq    $4, 32(%rdi)
  // ret

void iterator_increment (S & s) { ++s.i; }
  // addq    $4, 40(%rdi)
  // ret

// Conclusion: Incrementing a vector iterator is the same damn thing as 
// incrementing a pointer.

Nota: se si allocano array con newe si allocano oggetti non di classe (come plain int) o classi senza un costruttore definito dall'utente e non si desidera inizializzare inizialmente gli elementi, l'utilizzo di newarray allocati può avere vantaggi in termini di prestazioni perché std::vectorinizializza tutti gli elementi in valori predefiniti (0 per int, ad esempio) sulla costruzione (crediti a @bernie per avermi ricordato).


77
Chi ha inventato la dannata sintassi AT&T? Solo se lo sapessi ... :)
Mehrdad Afshari,

4
Questo non è vero per il compilatore Visual C ++. Ma per GCC lo è.
toto

5
Il punto nella mia risposta è che il vettore non deve essere più lento delle corrispondenti operazioni del puntatore. Certo, può essere (facile da ottenere abilitando anche la modalità debug) :)
Johannes Schaub - litb

18
+1 per "Indicizzare un vettore è la stessa dannata indicizzazione di un puntatore." e anche per le altre conclusioni.
Nawaz,

3
@ Piotr99 Non ho intenzione di discutere con te, ma quando impari l'assemblaggio dopo aver appreso le lingue di livello superiore, la sintassi Intel ha molto più senso di alcune versioni precedenti, con prefisso (numeri), suffissi (istruzioni) e oscuri (accesso alla memoria ) natura della sintassi AT&T.
Cole Johnson,

73

Preambolo per persone con microottimizzatore

Ricorda:

"I programmatori sprecano enormi quantità di tempo pensando o preoccupandosi della velocità delle parti non critiche dei loro programmi e questi tentativi di efficienza hanno effettivamente un forte impatto negativo quando si considerano il debug e la manutenzione. Dovremmo dimenticare piccole efficienze, diciamo Il 97% delle volte: l'ottimizzazione prematura è la radice di tutti i mali. Eppure non dovremmo rinunciare alle nostre opportunità in quel 3% critico ".

(Grazie alla metamorfosi per la citazione completa)

Non usare un array C invece di un vettore (o qualsiasi altra cosa) solo perché ritieni che sia più veloce in quanto dovrebbe essere di livello inferiore. Ti sbaglieresti.

Usa di default il vettore (o il contenitore sicuro adattato alle tue necessità), quindi se il tuo profiler dice che è un problema, vedi se puoi ottimizzarlo, usando un algoritmo migliore o cambiando contenitore.

Detto questo, possiamo tornare alla domanda originale.

Matrice statica / dinamica?

Le classi di array C ++ si comportano meglio dell'array C di basso livello perché sanno molto di se stesse e possono rispondere alle domande che gli array C non possono fare. Sono in grado di pulire dopo se stessi. E, cosa ancora più importante, di solito sono scritti usando template e / o inline, il che significa che ciò che appare a un sacco di codice nel debug si risolve in un codice scarso o nullo prodotto nella build del rilascio, il che significa nessuna differenza con la loro concorrenza meno sicura integrata.

Tutto sommato, rientra in due categorie:

Matrici dinamiche

L'uso di un puntatore a un array malloc-ed / new-ed sarà nella migliore delle ipotesi veloce come la versione std :: vector e molto meno sicuro (vedi il post di litb ).

Quindi usa uno std :: vector.

Matrici statiche

L'uso di un array statico sarà nella migliore delle ipotesi:

Quindi usa uno std :: array .

Memoria non inizializzata

A volte, l'utilizzo vectordi un buffer invece di un raw comporta un costo visibile perché vectorinizializzerà il buffer in fase di costruzione, mentre il codice che sostituisce non lo ha fatto, come ha osservato Bernie nella sua risposta .

Se questo è il caso, puoi gestirlo usando un unique_ptrinvece di un vectoro, se il caso non è eccezionale nella tua codeline, scrivi effettivamente una classe buffer_ownerche sarà proprietaria di quella memoria e ti darà un accesso facile e sicuro ad essa, incluso bonus come ridimensionarlo (usando realloc?) o qualunque cosa ti serva.


1
Grazie anche per l'indirizzamento di matrici statiche - std :: vector è inutile se non ti è permesso allocare dinamicamente memoria per motivi di prestazioni.
Tom,

10
Quando dici "L'uso di un array statico sarà veloce quanto la versione boost :: array" mostra quanto sei distorto. Dovrebbe essere l'altro, Boost: l'array può essere nella migliore delle ipotesi veloce come gli array statici.
toto

3
@toto: è un malinteso: dovresti leggerlo come "L'uso di un array statico sarà nella migliore delle ipotesi ((più veloce della versione boost :: array) && (molto meno sicuro))". Modificherò il post per chiarire questo. A proposito, grazie per il beneficio del dubbio.
paercebal,

1
che dire di std :: array?
paulm,

4
Mostra sempre il preventivo completo. "I programmatori sprecano enormi quantità di tempo pensando o preoccupandosi della velocità delle parti non critiche dei loro programmi e questi tentativi di efficienza hanno effettivamente un forte impatto negativo quando si considerano il debug e la manutenzione. Dovremmo dimenticare piccole efficienze, diciamo Il 97% delle volte: l'ottimizzazione prematura è la radice di tutti i mali. Eppure non dovremmo rinunciare alle nostre opportunità in quel 3% critico. " Altrimenti diventa un soundbite insignificante.
metamorfosi

32

I vettori sono array sotto il cofano. Le prestazioni sono le stesse.

Un punto in cui è possibile riscontrare un problema di prestazioni non è il dimensionamento corretto del vettore per cominciare.

Quando un vettore si riempie, si ridimensionerà e ciò può implicare una nuova allocazione di array, seguita da n costruttori di copie, seguita da circa n chiamate di distruttore, seguita da una cancellazione di array.

Se la costruzione / distruzione è costosa, è molto meglio rendere il vettore della dimensione corretta per cominciare.

C'è un modo semplice per dimostrarlo. Crea una classe semplice che mostra quando viene costruita / distrutta / copiata / assegnata. Crea un vettore di queste cose e inizia a spingerle sul retro del vettore. Quando il vettore si riempie, ci sarà una cascata di attività mentre il vettore si ridimensiona. Quindi riprovare con il vettore dimensionato in base al numero previsto di elementi. Vedrai la differenza.


4
Pendantry: la performance ha lo stesso grande O. std :: vector fa un po 'di contabilità, che presumibilmente costa un piccolo lasso di tempo. OTOH, finisci per fare gran parte della stessa contabilità quando arrotoli le tue matrici dinamiche.
dmckee --- ex gattino moderatore

si, capisco. Il punto forte della sua domanda, però, era quali sono le differenze di prestazioni ..... Ho provato a risolverlo.
EvilTeach del

Gcc's std :: vector aumenta effettivamente la capacità uno a uno se chiami push_back.
bjhend,

3
@bjhend Quindi gcc std::vectorsembra non conforme agli standard? Credo che lo standard richieda che vector::push_backabbia ammortizzato la complessità costante e che aumentare la capacità di 1 su ciascuna push_backsarà n ^ 2 complessità dopo aver tenuto conto di realloc. - presumere una sorta di aumento esponenziale della capacità push_backe insert, in caso contrario, si reserveavrà al massimo un aumento costante dei fattori nelle copie di contenuti vettoriali. Un fattore di crescita del vettore esponenziale 1,5 significherebbe ~ 3x quante copie se non ci riuscissi reserve().
Yakk - Adam Nevraumont,

3
@bjhend ti sbagli. La norma proibisce la crescita esponenziale: § 23.2.3, il paragrafo 16 dice "La tabella 101 elenca le operazioni che sono fornite per alcuni tipi di container di sequenza ma non per altri. Un'implementazione deve fornire queste operazioni per tutti i tipi di container mostrati nella colonna" container ", e devono attuarli in modo da prendere il tempo costante ammortizzato. " (la tabella 101 è quella con push_back al suo interno). Ora per favore smetti di diffondere FUD. Nessuna implementazione tradizionale viola questo requisito. La libreria C ++ standard di Microsoft cresce con un fattore 1,5x e GCC cresce con un fattore 2x.
R. Martinho Fernandes,

27

Per rispondere a qualcosa che Mehrdad disse:

Tuttavia, potrebbero esserci casi in cui sono ancora necessari array. Quando si interfaccia con codice di basso livello (ovvero assembly) o vecchie librerie che richiedono array, potrebbe non essere possibile utilizzare i vettori.

Per niente vero. I vettori si degradano bene in matrici / puntatori se si utilizza:

vector<double> vector;
vector.push_back(42);

double *array = &(*vector.begin());

// pass the array to whatever low-level code you have

Questo funziona per tutte le principali implementazioni STL. Nel prossimo standard, dovrà funzionare (anche se oggi va bene).


1
Lo standard attuale non dice nulla del genere. È implicito ed è implementato come memoria continua. Ma lo standard dice semplicemente che si tratta di un contenitore ad accesso casuale (usando iteratori). Il prossimo standard sarà esplicito.
Frank Krueger,

1
& * v.begin () applica semplicemente l'operatore & al risultato della de-referenziazione dell'iteratore. La de-referenziazione può restituire QUALSIASI tipo. L'utilizzo dell'indirizzo dell'operatore può nuovamente restituire QUALSIASI tipo. Lo standard non definisce questo come un puntatore in un'area contigua della memoria.
Frank Krueger,

15
In effetti, il testo originale dello Standard del 1998 non lo richiedeva, ma nel 2003 c'era un addendum che lo affrontava, quindi è veramente coperto dallo Standard. herbsutter.wordpress.com/2008/04/07/…
Nemanja Trifunovic il

2
C ++ 03 dice esplicitamente che &v[n] == &v[0] + nè valido fornito nè all'interno dell'intervallo di dimensioni. Il paragrafo che contiene questa affermazione non è cambiato con C ++ 11.
bjhend,

2
perché non usare semplicemente std :: vector :: data ()?
paulm,

15

Hai ancora meno motivi per usare array semplici in C ++ 11.

Esistono 3 tipi di array in natura dal più veloce al più lento, a seconda delle caratteristiche che hanno (ovviamente la qualità dell'implementazione può rendere le cose molto veloci anche per il caso 3 nell'elenco):

  1. Statico con dimensioni note al momento della compilazione. ---std::array<T, N>
  2. Dinamico con dimensioni note in fase di esecuzione e mai ridimensionate. L'ottimizzazione tipica qui è che se l'array può essere allocato direttamente nello stack. - Non disponibile . Forse dynarrayin C ++ TS dopo C ++ 14. In C ci sono VLA
  3. Dinamico e ridimensionabile in fase di esecuzione. ---std::vector<T>

Per 1. matrici statiche semplici con numero fisso di elementi, utilizzare std::array<T, N>in C ++ 11.

Per 2. matrici di dimensioni fisse specificate in fase di esecuzione, ma che non cambieranno le loro dimensioni, si discute in C ++ 14 ma è stato spostato in una specifica tecnica e infine realizzato in C ++ 14.

Per 3. std::vector<T> chiederà solitamente memoria nell'heap . Ciò potrebbe avere conseguenze sulle prestazioni, sebbene sia possibile utilizzarlo std::vector<T, MyAlloc<T>>per migliorare la situazione con un allocatore personalizzato. Il vantaggio rispetto a T mytype[] = new MyType[n];è che è possibile ridimensionarlo e che non decadrà in un puntatore, come fanno gli array semplici.

Utilizzare i tipi di libreria standard citati per evitare che gli array decadano con i puntatori . Risparmierai tempo di debug e le prestazioni sono esattamente le stesse degli array semplici se usi lo stesso set di funzionalità.


2
std :: dynarray. Dopo aver esaminato i commenti dell'ente nazionale a n3690, questo componente della biblioteca è stato votato dal documento di lavoro C ++ 14 in una specifica tecnica separata. Questo contenitore non fa parte del progetto C ++ 14 a partire da n3797. da en.cppreference.com/w/cpp/container/dynarray
Mohamed El-Nakib

1
ottima risposta. breve e sintetico, ma più dettagli di tutti.
Mohamed El-Nakib,

6

Vai con STL. Non ci sono penalità di prestazione. Gli algoritmi sono molto efficienti e fanno un buon lavoro nel gestire i tipi di dettagli a cui la maggior parte di noi non penserebbe.


5

STL è una libreria fortemente ottimizzata. In effetti, si suggerisce persino di utilizzare STL nei giochi in cui potrebbero essere necessarie prestazioni elevate. Le matrici sono troppo soggette ad errori per essere utilizzate nelle attività quotidiane. I compilatori di oggi sono anche molto intelligenti e possono davvero produrre un codice eccellente con STL. Se sai cosa stai facendo, di solito STL può fornire le prestazioni necessarie. Ad esempio inizializzando i vettori alla dimensione richiesta (se si conosce dall'inizio), è possibile ottenere sostanzialmente le prestazioni dell'array. Tuttavia, potrebbero esserci casi in cui sono ancora necessari array. Quando si interfaccia con codice di basso livello (ovvero assembly) o vecchie librerie che richiedono array, potrebbe non essere possibile utilizzare i vettori.


4
dato che il vettore è contiguo, è comunque abbastanza semplice interfacciarsi con le librerie che richiedono array.
Greg Rogers,

Sì, ma se si desidera pasticciare con le cose interne del vettore, ci sarebbe meno vantaggio nell'usare un vettore. A proposito, la parola chiave era "potrebbe non esserlo".
Mehrdad Afshari,

3
c'è solo un caso che conosco dove i vettori non possono essere usati: se la dimensione è 0. allora & a [0] o & * a.begin () non funzioneranno. c ++ 1x risolverà il problema introducendo una funzione a.data () che restituisce il buffer interno mantenendo gli elementi
Johannes Schaub - litb

Lo scenario specifico nella mia mente quando ho scritto che si trattava di array basati su stack.
Mehrdad Afshari,

1
Interfaccia vettoriale o qualsiasi contenitore contiguo con C: vec.data()per dati e vec.size()dimensioni. È così facile
Germán Diago,

5

Sul contributo di duli .

La conclusione è che le matrici di numeri interi sono più veloci dei vettori di numeri interi (5 volte nel mio esempio). Tuttavia, matrici e vettori hanno circa la stessa velocità per dati più complessi / non allineati.


3

Se si compila il software in modalità debug, molti compilatori non incorporeranno le funzioni di accesso del vettore. Ciò renderà l'implementazione del vettore stl molto più lenta nei casi in cui le prestazioni sono un problema. Semplifica anche il debug del codice poiché puoi vedere nel debugger quanta memoria è stata allocata.

In modalità ottimizzata, mi aspetto che il vettore stl si avvicini all'efficienza di un array. Questo perché molti dei metodi vettoriali sono ora incorporati.


Questo è importante da menzionare. La creazione di profili di debug STL è molto, molto lenta. Ed è uno dei motivi per cui la gente STL è lenta.
Erik Aronesty,

3

Vi è sicuramente un impatto sulle prestazioni nell'uso di un std::vectorarray vs un raw quando si desidera un buffer non inizializzato (ad esempio, da utilizzare come destinazione memcpy()). Un std::vectorinizializzerà tutti i suoi elementi usando il costruttore predefinito. Un array grezzo non lo farà.

La specifica c ++ per il std:vectorcostruttore che prende un countargomento (è la terza forma) afferma:

`Costruisce un nuovo contenitore da una varietà di origini dati, opzionalmente usando un allocatore allocatore fornito dall'utente.

3) Costruisce il contenitore con il numero di istanze di T. inserite per impostazione predefinita. Non vengono eseguite copie.

Complessità

2-3) Conteggio lineare

Un array grezzo non comporta questo costo di inizializzazione.

Vedi anche Come posso evitare std :: vector <> per inizializzare tutti i suoi elementi?


2

La differenza di prestazioni tra i due dipende molto dall'implementazione - se si confronta uno std :: vector mal implementato con un'implementazione ottimale dell'array, l'array vincerebbe, ma si rigirerebbe e il vettore vincerebbe ...

Fintanto che si confrontano le mele con le mele (sia l'array che il vettore hanno un numero fisso di elementi o entrambi vengono ridimensionati dinamicamente), penso che la differenza di prestazioni sia trascurabile fintanto che segui la pratica di codifica STL. Non dimenticare che l'utilizzo di contenitori C ++ standard ti consente anche di utilizzare gli algoritmi pre-roll che fanno parte della libreria C ++ standard e che la maggior parte di essi avrà probabilmente prestazioni migliori rispetto all'implementazione media dello stesso algoritmo che costruisci tu stesso .

Detto questo, IMHO il vettore vince in uno scenario di debug con un debug STL poiché la maggior parte delle implementazioni STL con una modalità di debug adeguata può almeno evidenziare / catturare gli errori tipici commessi dalle persone quando lavorano con contenitori standard.

Oh, e non dimenticare che l'array e il vettore condividono lo stesso layout di memoria in modo da poter utilizzare i vettori per passare i dati al codice C o C ++ legacy che prevede array di base. Tieni presente che la maggior parte delle scommesse sono disattivate in quello scenario, tuttavia, e hai di nuovo a che fare con memoria grezza.


1
Credo che per soddisfare i requisiti di prestazione (O (1) ricerche e inserimenti), è quasi necessario implementare std :: vector <> utilizzando gli array dinamici. Certamente questo è il modo ovvio per farlo.
dmckee --- ex-moderatore gattino

Non solo i requisiti di prestazione, ma anche il requisito che l'archiviazione è contigua. Una cattiva implementazione vettoriale metterà troppi livelli di indiretta tra l'array e l'API. Una buona implementazione del vettore consentirà il codice incorporato, il SIMD utilizzato sui loop, ecc.
Max Lybbert

Un'implementazione vettoriale errata come descritta non sarebbe conforme allo standard. Se si desidera l'indirizzamento indiretto, std::dequepotrebbe essere utilizzato.
Phil1970,

1

Se non è necessario regolare dinamicamente la dimensione, si ha l'overhead della memoria per il salvataggio della capacità (un puntatore / size_t). Questo è tutto.


1

Potrebbe esserci un caso limite in cui hai un accesso vettoriale all'interno di una funzione inline all'interno di una funzione inline, in cui sei andato oltre ciò che il compilatore sarà in linea e forzerà una chiamata di funzione. Sarebbe così raro che non valga la pena preoccuparsi - in generale concordo con il litb .

Sono sorpreso che nessuno lo abbia ancora menzionato - non preoccuparti delle prestazioni fino a quando non si sarà dimostrato un problema, quindi benchmark.


1

Direi che la preoccupazione principale non sono le prestazioni, ma la sicurezza. Puoi fare molti errori con le matrici (considera il ridimensionamento, ad esempio), in cui un vettore ti risparmierebbe molto dolore.


1

I vettori usano un po 'più di memoria degli array poiché contengono le dimensioni dell'array. Aumentano anche la dimensione del disco rigido dei programmi e probabilmente l'impronta di memoria dei programmi. Questi aumenti sono minuscoli, ma possono interessare se stai lavorando con un sistema incorporato. Sebbene la maggior parte dei luoghi in cui queste differenze contano siano luoghi in cui si utilizzerebbe C anziché C ++.


2
Se questo è importante, ovviamente non stai usando array di dimensioni dinamiche e, come tale, i tuoi array non devono cambiare dimensione. (Se lo facessero, dovresti conservare le dimensioni in qualche modo). Pertanto, potresti anche usare boost :: array a meno che non mi sbagli - e cosa ti spinge a dire che è necessario "memorizzare le dimensioni" da qualche parte?
Arafangion,

1

Il seguente semplice test:

Spiegazione del test delle prestazioni Cray Array vs Vector

contraddice le conclusioni tratte da "Confronto del codice assembly generato per operazioni di indicizzazione, dereferenziazione e incremento di base su vettori e matrici / puntatori".

Deve esserci una differenza tra array e vettori. Il test dice così ... provalo, il codice è lì ...


1

A volte le matrici sono effettivamente migliori dei vettori. Se si manipola sempre un insieme di oggetti a lunghezza fissa, le matrici sono migliori. Considera i seguenti frammenti di codice:

int main() {
int v[3];
v[0]=1; v[1]=2;v[2]=3;
int sum;
int starttime=time(NULL);
cout << starttime << endl;
for (int i=0;i<50000;i++)
for (int j=0;j<10000;j++) {
X x(v);
sum+=x.first();
}
int endtime=time(NULL);
cout << endtime << endl;
cout << endtime - starttime << endl;

}

dove si trova la versione vettoriale di X.

class X {
vector<int> vec;
public:
X(const vector<int>& v) {vec = v;}
int first() { return vec[0];}
};

e la versione dell'array di X è:

class X {
int f[3];

public:
X(int a[]) {f[0]=a[0]; f[1]=a[1];f[2]=a[2];}
int first() { return f[0];}
};

La versione dell'array di main () sarà più veloce perché evitiamo il sovraccarico di "new" ogni volta nel ciclo interno.

(Questo codice è stato pubblicato da me in comp.lang.c ++).


1

Se stai usando i vettori per rappresentare un comportamento multidimensionale, c'è un impatto sulle prestazioni.

I vettori 2d + causano un calo delle prestazioni?

L'essenza è che c'è una piccola quantità di overhead con ogni sotto-vettore che ha informazioni sulla dimensione e che non ci sarà necessariamente una serializzazione dei dati (come accade con le matrici c multidimensionali). Questa mancanza di serializzazione può offrire maggiori opportunità di micro ottimizzazione. Se stai eseguendo array multidimensionali, potrebbe essere meglio estendere semplicemente std :: vector e ruotare la tua funzione di bit get / set / resize.


0

Supponendo un array a lunghezza fissa (ad es. int* v = new int[1000];Vs std::vector<int> v(1000);, con la dimensione di vessere fissato fisso a 1000), l'unica considerazione prestazionale che conta davvero (o almeno che contava per me quando ero in un dilemma simile) è la velocità di accesso a un elemento. Ho cercato il codice vettoriale dell'STL ed ecco cosa ho trovato:

const_reference
operator[](size_type __n) const
{ return *(this->_M_impl._M_start + __n); }

Questa funzione sarà sicuramente sottolineata dal compilatore. Quindi, fintanto che l'unica cosa che prevedi di fare vè accedere ai suoi elementi operator[], sembra che non ci dovrebbe essere alcuna differenza nelle prestazioni.

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.