Ottimizzare C++/Ottimizzazione del codice C++/Costruzioni e distruzioni: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
m Bot: Sostituzione automatica (-[[Categoria:Ottimizzare C++|Ottimizzare C++/Ottimizzazione del codice C++/ +[[Categoria:Ottimizzare C++|) |
Nessun oggetto della modifica |
||
Riga 8:
=== Valore di ritorno di funzioni ===
'''Per le funzioni che non siano espanse ''inline'', cerca di dichiarare il tipo di ritorno <code>void</code> o <code>bool</code> o intero o puntatore o riferimento. Comunque, evita di dichiarare un tipo di ritorno la cui copia sposta oltre 8 byte. Se non fosse fattibile, almeno costruisci
Nella compilazione di una funzione non espansa ''inline'', il compilatore non può sapere se il valore di ritorno verrà usato, e quindi lo deve comunque generare.
Generare un intero o un puntatore o un riferimento costa poco o niente, ma generare numeri a virgola mobile od oggetti più complessi richiede tempo.
Se la copia comporta l'allocazione di risorse, il tempo richiesto è enormemente maggiore, ma anche senza allocazioni, il tempo richiesto cresce al crescere del numero delle word che vengono copiate quando si copia un oggetto di tale tipo.
Comunque, se si costruisce l'oggetto da ritornare nelle stesse istruzioni <code>return</code>, senza quindi assegnare tale valore a una variabile, si sfrutta l'ottimizzazione garantita dallo standard detta ''Return Value Optimization'', che previene la creazione di oggetti temporanei.
Alcuni compilatori riescono a evitare la creazione di oggetti temporanei anche se sono legati a variabili locali (''Named Return Value Optimization''), ma in generale questo non è garantito.▼
▲Alcuni compilatori riescono a evitare la creazione di oggetti temporanei, anche se questi sono legati a variabili locali (con la cosiddetta ''Named Return Value Optimization''), ma in generale questo non è garantito.
Per verificare se viene attuata una di tali ottimizzazioni, inserisci un contatore nei costruttori, nei distruttori, e negli operatori di assegnamento della classe dell'oggetto ritornato.▼
▲Per verificare se viene attuata una di tali ottimizzazioni,
Nel caso non risultassero applicate ottimizzazioni, ricorri a una delle seguenti tecniche alternative:
* Rendi la funzione <code>void</code>, e aggiungile un argomento passato per riferimento, che funge da valore di ritorno.
* Trasforma la funzione in un costruttore del tipo ritornato, che riceve gli stessi parametri della funzione.
* Fai in modo che la funzione restituisca un oggetto di un tipo ausiliario che ruba le risorse e le cede all'oggetto destinazione, senza copiarle.
* Usa un ''expression template'', che è una tecnica avanzata, facente parte del paradigma di programmazione detto [[w:en:Template metaprogramming|Template metaprogramming]].
* Usa un ''rvalue reference'', introdotto dallo standard C++0x.
=== Spostamento di variabili all'esterno di cicli ===
'''Se una variabile è dichiarata
Se la variabile è dichiarata
Tuttavia, in molti casi un assegnamento costa esattamente quanto una coppia costruzione+distruzione, per cui in tali casi non ci sono vantaggi a spostare la dichiarazione
=== Operatore di assegnamento ===
'''In un overload dell'operatore di assegnamento (operator=), se sei sicuro che non solleverà eccezioni, non usare la tecnica ''copy&swap''
La tecnica più efficiente per copiare un oggetto è imitare il costruttore di copia, cioè prima copiare gli oggetti base, e poi gli oggetti membro, in ordine di dichiarazione.▼
Tuttavia, tale tecnica non è ''exception-safe'', cioè corre il rischio di non chiamare il distruttore di qualche oggetto nel caso venga sollevata un'eccezione durante la copia.
▲La tecnica più efficiente per copiare un oggetto è imitare il costruttore di copia, cioè prima copiare gli oggetti base e poi gli oggetti membro, in ordine di dichiarazione.
Pertanto, se c'è la possibilità che durante la copia venga sollevata un'eccezione, si deve usare una tecnica ''exception-safe'', che tuttavia non avrà prestazioni ottimali.
La tecnica di assegnamento ''exception-safe'' più elegante è quella detta ''copy&swap'', esemplificata dal seguente codice in cui <code>C</code> rappresenta il nome della classe:
<source lang=cpp>
C& C::operator=(C new_value) {
Line 58 ⟶ 62:
[[Categoria:Ottimizzare C++|Costruzioni e distruzioni]]
{{Avanzamento|
|