Esistono limiti pratici all'utilizzo solo di std :: string anziché di array di caratteri e std :: vector / list anziché di array in c ++?

StackOverflow https://stackoverflow.com/questions/801385

Domanda

Uso ossessivamente vettori, elenchi, stringhe e stringhe nel mio codice. Ci sono delle catture 22 coinvolte che dovrebbero rendermi più interessato all'utilizzo di array di volta in volta, invece di char e wchar?

Fondamentalmente, se si lavora in un ambiente che supporta la libreria di modelli standard, in ogni caso è meglio usare i tipi primitivi?

È stato utile?

Soluzione

Per il 99% delle volte e per il 99% delle implementazioni della libreria standard, scoprirai che std :: vectors sarà abbastanza veloce e che la comodità e la sicurezza che ottieni dall'utilizzarli supereranno di gran lunga i costi di prestazioni ridotti.

Per quei casi molto rari in cui hai davvero bisogno di codice bare metal, puoi trattare un vettore come un array in stile C:

vector <int> v( 100 );
int * p = &v[0];
p[3] = 42;

Lo standard C ++ garantisce che i vettori siano assegnati in modo contiguo, quindi questo è garantito per funzionare.

Per quanto riguarda le stringhe, il fattore convenienza diventa quasi schiacciante e i problemi di prestazioni tendono a scomparire. Se vai alle stringhe in stile C, tornerai anche all'uso di funzioni come strlen (), che sono intrinsecamente molto inefficaci.

Per quanto riguarda gli elenchi, dovresti pensarci due volte, e probabilmente tre volte, prima di usarli, sia per la tua implementazione che per lo standard. La stragrande maggioranza dei problemi informatici viene risolta meglio utilizzando un vettore / array. Gli elenchi dei motivi che appaiono così spesso nella letteratura sono in gran parte perché sono una struttura dati conveniente per gli autori di libri di testo e corsi di formazione da utilizzare per spiegare i puntatori e l'allocazione dinamica in una sola volta. Parlo qui come ex autore di corsi di formazione.

Altri suggerimenti

Vorrei attenermi alle classi STL (vettori, stringhe, ecc.). Sono più sicuri, più facili da usare, più produttivi, con meno probabilità di avere perdite di memoria e, AFAIK, effettuano alcuni controlli aggiuntivi del tempo di esecuzione dei limiti, almeno al momento del DEBUG (Visual C ++).

Quindi, misurare le prestazioni. Se si identificano i colli di bottiglia nelle classi STL, passare all'utilizzo di stringhe e array di stile C.

Dalla mia esperienza, le possibilità di avere il collo di bottiglia nell'uso di vettore o stringa sono molto basse.

Un problema è il sovraccarico quando si accede agli elementi. Anche con il vettore e la stringa quando si accede a un elemento per indice, è necessario prima recuperare l'indirizzo del buffer, quindi aggiungere l'offset (non lo si fa manualmente, ma il compilatore emette tale codice). Con l'array raw hai già l'indirizzo del buffer. Questa ulteriore direzione indiretta può comportare un notevole sovraccarico in alcuni casi ed è soggetta alla profilazione quando si desidera migliorare le prestazioni.

Se non hai bisogno di risposte in tempo reale, segui il tuo approccio. Sono più sicuri dei caratteri.

Occasionalmente puoi imbatterti in scenari in cui puoi ottenere prestazioni o utilizzo della memoria migliori facendo alcune cose da te (ad esempio, std :: string in genere ha circa 24 byte di overhead, 12 byte per i puntatori nello std :: string stesso e un blocco di intestazione sul suo pezzo assegnato dinamicamente).

Ho lavorato a progetti in cui la conversione da std :: string a const char * ha salvato la memoria notevole (10 di MB). Non credo che questi progetti siano quelli che definirei tipici.

Oh, usare STL danneggerà i tuoi tempi di compilazione, e ad un certo punto potrebbe essere un problema. Quando il tuo progetto si traduce in oltre un GB di file oggetto passati al linker, ti consigliamo di considerare quanto di questo è gonfio modello.

Ho lavorato su diversi progetti in cui l'overhead di memoria per le stringhe è diventato problematico.

Vale la pena considerare in anticipo come ridimensionare l'applicazione. Se devi archiviare un numero illimitato di stringhe, l'utilizzo di const char * in una tabella di stringhe gestita a livello globale può farti risparmiare enormi quantità di memoria.

Ma generalmente, usa sicuramente i tipi STL a meno che non ci sia un ottimo motivo per fare diversamente.

Credo che la tecnica di allocazione della memoria predefinita sia un buffer per i vettori e le stringhe sia quella che alloca il doppio della quantità di memoria ogni volta che la memoria attualmente allocata viene utilizzata. Questo può essere uno spreco. Ovviamente puoi fornire un allocatore personalizzato ...

L'altra cosa da considerare è stack vs. heap. Le matrici e le stringhe di dimensioni statiche possono trovarsi nello stack, o almeno il compilatore gestisce la gestione della memoria per te. I compilatori più recenti gestiranno anche array di dimensioni dinamiche se forniscono la funzionalità C99 / C ++ 0x pertinente. I vettori e le stringhe utilizzeranno sempre l'heap e questo può introdurre problemi di prestazioni se si hanno vincoli molto stretti.

Come regola generale usa ciò che è già lì a meno che non danneggi il tuo progetto con la sua velocità / memoria ambientale ... probabilmente scoprirai che per il 99% delle cose le classi fornite da STL ti fanno risparmiare tempo e fatica con poco o niente impatto sulle prestazioni delle applicazioni. (ovvero "evitare l'ottimizzazione prematura")

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top