Ottimizzare C++/Scrivere codice C++ efficiente/Costrutti che migliorano le prestazioni: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
RamaccoloBot (discussione | contributi)
Riportate modifiche da en.wikibooks
Riga 4:
 
In questa sezione si presentano le linee-guida per approfittare di tali costrutti.
 
=== Uso deiI tipi più efficienti ===
 
'''PerQuando memorizzare indefinisci un oggetto deiper numerimemorizzare interiun numero intero, usa il tipo <code>int</code> o il tipo <code>unsigned int</code>, a meno che sia necessario un tipo più lungo; quando definisci un oggetto per memorizzare deiun carattericarattere, usa il tipo <code>char</code>, a meno che serva il tipo <code>wchar_t</code>; e quando definisci un oggetto per memorizzare deiun numerinumero a virgola mobile, usa il tipo <code>double</code>, a meno che sia necessario il tipo <code>long double</code>. Se l'oggetto composto risultante è medio o grande, sostituisci tutti i tipi interi con il tipo intero più piccolo in grado di contenerlo, ma senza usare i ''bit-field'', e sostituisci tutti i tipi a virgola mobile con il tipo <code>float</code>, a meno che sia necessaria maggiore precisione.'''
 
I tipi <code>int</code> e <code>unsigned int</code> sono per definizione quelli più efficienti su qualunque piattaforma.
 
IIl tipitipo <code>double</code> sonoè efficientiefficiente quanto iil tipo <code>float</code>, ma sonoè più precisipreciso.
 
Alcuni tipi di processore elaborano più velocemente gli oggetti di tipo <code>signed char</code>, mentre altri elaborano più velocemente gli oggetti di tipo <code>unsigned char</code>.
Pertanto, sia in C eche in C++ esisteè stato introdotto il tipo <code>char</code>, diverso dal tipo <code>signed char</code>, che corrisponde al tipo di carattere elaborato più velocemente suldal processore target.
 
Il tipo <code>char</code> può contenere solo piccoli insiemi di caratteri; tipicamente fino a un massimo di 255 caratteri distinti.
Per memorizzare set di caratteri più grandi, si deve ricorrere al tipo <code>wchar_t</code>, che ovviamente è meno efficiente.
 
Nel caso di interinumeri contenuti in arrayun medioggetto composto di media o grandigrande dimensione, o in collezioniuna collezione che si presume sarannosarà tipicamentedi mediemedia o grandigrande dimensione, è meglio minimizzare la dimensione in byte dell'oggetto composto o della collezione.
Questo si può fare sostituendo gli <code>int</code> con <code>short</code> o con <code>signed char</code>, sostituendo gli <code>unsigned int</code> con <code>unsigned short</code> o con <code>unsigned char</code>, e sostituendo i <code>double</code> con i <code>float</code>.
Per esempio, per memorizzare un numero intero che può essere compreso tra 0 e 1000, si può usare un <code>unsigned short</code>, mentre per memorizzare un numero intero che può essere compreso tra -100 e 100, si può usare un <code>signed char</code>.
 
I bit-field contribuirebbero a minimizzare la dimensione in byte dell'arrayoggetto o della collezione, ma la loro elaborazione introduce un rallentamento che potrebbe essere eccessivo; pertanto, perposponi cuila andrebbero eventualmente introdottiloro solointroduzione inalla fase di ottimizzazione.
 
=== Gli oggetti-funzione ===
 
'''Invece di passare come argomento di funzione un puntatore a funzione, passa un [[w:en:Function object|oggetto-funzione]], o, se stai usando lo standard [[w:C++0x|C++0x]], un'espressione lambda.'''
 
Per esempio, se hai il seguente array di strutture:
 
<source lang=cpp>
struct S {
int a, b;
};
S arr[n_voci];
</source>
 
e vuoi ordinarlo in base al campo <code>b</code>, potresti definire la seguente funzione di confronto:
 
<source lang=cpp>
bool confronta(const S& s1, const S& s2) {
return s1.b < s2.b;
}
</source>
 
e passarla all'algoritmo <code>std::sort</code>:
 
<source lang=cpp>
std::sort(arr, arr + n_voci, confronta);
</source>
 
Ma probabilmente è più efficiente definire la seguente classe di oggetto-funzione (nota anche come ''funtore''):
 
<source lang=cpp>
struct Comparatore {
bool operator()(const S& s1, const S& s2) const {
return s1.b < s2.b;
}
};
</source>
 
e passarne un'istanza temporanea all'algoritmo <code>std::sort</code>:
 
<source lang=cpp>
std::sort(arr, arr + n_voci, Comparatore());
</source>
 
Le funzioni degli oggetti-funzione di solito sono espansi ''inline'', e perciò sono altrettanto efficienti quanto il codice scritto sul posto, mentre le funzioni passate per puntatore vengono raramente espanse ''inline''.
 
Le espressioni lambda sono implementate come oggetti-funzione, e quindi hanno le loro stesse prestazioni.
 
=== Operatore <code>delete</code> con puntatori nulli ===
Line 224 ⟶ 291:
</source>
 
=== Uso dei tipi più efficienti ===
 
'''Per memorizzare in un oggetto dei numeri interi, usa il tipo <code>int</code> o il tipo <code>unsigned int</code>, a meno che sia necessario un tipo più lungo; per memorizzare dei caratteri usa il tipo <code>char</code>, a meno che serva il tipo <code>wchar_t</code>; e per memorizzare dei numeri a virgola mobile, usa il tipo <code>double</code>, a meno che sia necessario il tipo <code>long double</code>. Se l'oggetto risultante è medio o grande, sostituisci i tipi interi con il tipo intero più piccolo in grado di contenerlo, ma senza usare i ''bit-field'', e sostituisci i tipi a virgola mobile con il tipo <code>float</code>, a meno che sia necessaria maggiore precisione.'''
 
I tipi <code>int</code> e <code>unsigned int</code> sono per definizione quelli più efficienti su qualunque piattaforma.
 
I tipi <code>double</code> sono efficienti quanto i <code>float</code>, ma sono più precisi.
 
Alcuni tipi di processore elaborano più velocemente gli oggetti di tipo <code>signed char</code>, mentre altri elaborano più velocemente gli oggetti di tipo <code>unsigned char</code>.
Pertanto, in C e in C++ esiste il tipo <code>char</code> che corrisponde al tipo di carattere elaborato più velocemente sul processore target.
 
Il tipo <code>char</code> può contenere solo piccoli insiemi di caratteri; tipicamente fino a un massimo di 255 caratteri distinti.
Per memorizzare set di caratteri più grandi, si deve ricorrere al tipo <code>wchar_t</code>, che ovviamente è meno efficiente.
 
Nel caso di interi contenuti in array medi o grandi, o in collezioni che si presume saranno tipicamente medie o grandi, è meglio minimizzare la dimensione in byte della collezione.
Questo si può fare sostituendo gli <code>int</code> con <code>short</code> o <code>signed char</code>, sostituendo gli <code>unsigned int</code> con <code>unsigned short</code> o <code>unsigned char</code>, e sostituendo i <code>double</code> con i <code>float</code>.
Per esempio, per memorizzare un numero intero che può essere compreso tra 0 e 1000, si può usare un <code>unsigned short</code>, mentre per memorizzare un numero intero che può essere compreso tra -100 e 100, si può usare un <code>signed char</code>.
 
I bit-field contribuirebbero a minimizzare la dimensione in byte dell'array, ma la loro elaborazione introduce un rallentamento che potrebbe essere eccessivo, per cui andrebbero eventualmente introdotti solo in fase di ottimizzazione.
 
=== Uso di funzioni membro di contenitori ===