Ottimizzare C++/Scrivere codice C++ efficiente/Costrutti che migliorano le prestazioni: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
→Rappresentazione di simboli: aggiunta |
Nessun oggetto della modifica |
||
Riga 1:
{{Ottimizzare C++}}
Alcuni costrutti del linguaggio C++, se usati opportunamente, permettono di
In questa sezione si presentano le linee-guida per approfittare di tali costrutti.
Riga 13:
=== Funzioni <code>qsort</code> e <code>bsearch</code> ===
'''Invece delle funzioni della libreria standard del C <code>qsort</code> e
Le prime due funzioni richiedono necessariamente un puntatore a funzione, mentre le seconde due possono usare un oggetto-funzione (o, usando [[w:C++0x|C++0x]], un'espressione lambda).
I puntatori a funzione spesso non sono espansi ''inline'' e sono quindi meno efficienti degli oggetti-funzione.
=== Funzioni membro <code>const</code> ===
Riga 25:
Indicare <code>const</code> una funzione membro equivale a specificare tale argomento implicito come puntatore a <code>const</code>.
La linea-guida "Passaggio di argomenti alle funzioni" della sezione 3.3
=== Rappresentazione di simboli ===
Riga 33:
Un enumerato è implementato come un intero.
Tipicamente, rispetto ad un intero, una stringa occupa più spazio, ed è più lenta da copiare e da confrontare.
Inoltre, tale pratica è più sicura, in quanto se si sbaglia a scrivere la costante
=== Istruzioni <code>if</code> e <code>switch</code> ===
Riga 39:
Se devi confrontare un valore intero con una serie di valori costanti, invece di una serie di istruzioni <code>if</code>, usa un'istruzione <code>switch</code>.
I compilatori possono sfruttare la regolarità di tale istruzione per applicare alcune ottimizzazioni, in particolare se viene applicata la linea-guida
=== Collezioni incapsulate ===
Riga 46:
In fase di progettazione è difficile decidere quale struttura dati avrà prestazioni ottimali nell'uso effettivo dell'applicazione.
In fase di ottimizzazione, ci si può accorgere che cambiando il tipo di un contenitore, per esempio passando da <code>std::vector</code> a <code>std::list</code>, si ottengono prestazioni migliori.
Tuttavia, tale
Se una collezione è accessibile da una sola unità di compilazione, tale modifica avrà impatto solamente sul codice sorgente contenuto in tale file, e quindi non è necessario incapsulare tale collezione.
Se invece la collezione è accessibile direttamente da altre unità di compilazione, in futuro ci potrà essere una quantità enorme di codice che dovrà essere modificata a fronte di un cambio di contenitore, e quindi, per rendere fattibile in tempi ragionevoli tale ottimizzazione, si deve incapsulare il contenitore in una classe la
I contenitori STL attuano già parzialmente questo principio, ma alcune operazioni sono disponibili solo per alcuni contenitori, e altre hanno comportamento diverso al variare del contenitore.
Riga 58:
'''Nell'uso dei contenitori STL, a parità di prestazioni, fa' in modo di rendere intercambiabile il contenitore.'''
Per esempio, chiama <code>a.empty()</code> invece di <code>a.size() == 0</code>,
Purtroppo, non è sempre possibile scrivere del codice egualmente
Tuttavia, riducendo il numero di istruzioni dipendenti dal tipo di contenitore, se in fase di ottimizzazione si dovesse sostituire il contenitore con un altro, si dovrà modificare meno codice.
=== Espressioni lambda ===
'''Invece di scrivere un ciclo <code>for</code> su un contenitore STL, usa un algoritmo di STL con un'espressione lambda (usando la libreria [[http://www.boost.org/ Boost]] o C++0x).'''
Gli algoritmi di STL sono già dei cicli ottimizzati per gli specifici contenitori, ed evitano il rischio di introdurre erroneamente operazioni inefficienti.
Le espressioni lambda sono implementate come oggetti-funzione espansi ''inline'', e quindi sono altrettanto efficienti quanto il codice scritto sul posto.
Senza avere a disposizione la funzionalità lambda, nella
=== Scelta del contenitore di default ===
Riga 81:
Per insiemi più grandi, altri contenitori possono diventare gradualmente più efficienti a seconda delle operazioni, ma il <code>vector</code> rimane quello che ha minore occupazione di memoria (purché non ci sia capacità in eccesso), minor tempo di scansione completa, e maggiore località di riferimento.
=== Funzioni espanse
'''Se usi compilatori che consentono l'ottimizzazione dell'intero programma e l'espansione
Le funzioni espanse
Infine, dato che il codice intermedio delle funzioni espanse Le funzioni molto piccole, cioè un semplice assegnamento o una semplice istruzione <code>return</code>, quando espanse
Tuttavia, ogni volta che
Tra le routine non piccolissime, solo quelle critiche per la velocità verranno
<!--revisione giunta fino a qui-->
=== Valori dei casi di istruzioni <code>switch</code> ===
|