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

Contenuto cancellato Contenuto aggiunto
RamaccoloBot (discussione | contributi)
m Bot: Sostituzione automatica (-[[Categoria:Ottimizzare C++|Ottimizzare C++/Scrivere codice C++ efficiente/ +[[Categoria:Ottimizzare C++|)
Nessun oggetto della modifica
Riga 16:
Se tale operazione viene effettuata solamente ogni volta che un messaggio viene mostrato all'utente o scritto in un file di log, si ha la garanzia che non verrà eseguita troppo spesso.
Se invece la si effettua come operazione algoritmica, anche se pensata inizialmente per essere eseguita raramente, potrebbe finire per essere eseguita frequentemente.
 
=== Funzioni membro <code>static</code> ===
 
'''In ogni classe, dichiara <code>static</code> ogni funzione membro che non accede ai membri non-<code>static</code> di tale classe.'''
 
In altre parole, dichiara <code>static</code> tutte le funzioni membro che puoi.
 
In questo modo, non viene passato l'argomento implicito <code>this</code>.
 
=== Funzioni membro <code>virtual</code> ===
 
'''In ogni classe, definisci <code>virtual</code> il distruttore se e solo se la classe contiene almeno un'altra funzione membro <code>virtual</code>, e, a parte i costruttori e il distruttore, definisci <code>virtual</code> solamente le funzioni membro di cui prevedi la necessità di una ridefinizione.'''
 
A parità di condizioni, le classi che contengono almeno una funzione membro <code>virtual</code> occupano un po' più di spazio delle classi che non ne contengono, e glile oggettiistanze delle classi che contengono almeno una funzione membro <code>virtual</code> occupano un po' più di spazio e la loro costruzione richiede un po' più di tempo rispetto agli oggetti di classi che non contengono funzioni membro <code>virtual</code>.
 
LeInoltre, le funzioni membro <code>virtual</code> occupano un po' più di spazio e sono un po' più lente da chiamare delle funzioni membro non-<code>virtual</code>.
 
=== Derivazione <code>virtual</code> ===
 
'''Non usare sistematicamenteUsa la derivazione <code>virtual</code>, ma solo quando due o più classi devono condividere la rappresentazione di una classe base comune.'''
 
Le funzioni membro delle classi base derivate in modo <code>virtual</code> sono un po' più lente delle funzioni membro derivate in modo non-<code>virtual</code>.
Line 35 ⟶ 51:
Questo non costituisce un problema se la classe A non ha nessuna variabile membro non-<code>static</code>.
 
Se invece tale oggetto di classe A contiene qualche variabile membro, e si intende che tale variabile membro debba essere unicounica per ogni oggetto di classe C, si deve usare la derivazione <code>virtual</code>, nel seguente modo:
 
<source lang=cpp>
Line 45 ⟶ 61:
 
Questa situazione è l'unica in cui è necessaria la derivazione <code>virtual</code>.
 
=== Funzioni membro <code>virtual</code> ===
 
'''In ogni classe, non definire sistematicamente <code>virtual</code> tutte le funzioni membro, ma solo le funzioni membro di cui prevedi la necessità di una ridefinizione, a parte il distruttore, il quale deve essere definito <code>virtual</code> se e solo se la classe contiene almeno un'altra funzione membro <code>virtual</code>.'''
 
A parità di condizioni, le classi che contengono almeno una funzione membro <code>virtual</code> occupano un po' più spazio delle classi che non ne contengono, e gli oggetti delle classi che contengono almeno una funzione membro <code>virtual</code> occupano un po' più spazio e la loro costruzione richiede un po' più di tempo rispetto agli oggetti di classi che non contengono funzioni membro <code>virtual</code>.
 
Le funzioni membro <code>virtual</code> occupano po' più spazio e sono un po' più lente da chiamare delle funzioni membro non-<code>virtual</code>.
 
=== Funzioni membro <code>static</code> ===
 
'''In ogni classe, dichiara <code>static</code> ogni funzione membro che non accede ai membri non-<code>static</code> di tale classe.'''
 
In altre parole, dichiara <code>static</code> tutte le funzioni membro che puoi.
 
In questo modo, non viene passato l'argomento implicito <code>this</code>.
 
=== Template di classi polimorfiche ===
Riga 66:
'''Non definire template di classi polimorfiche.'''
 
I template di classe, ogni volta che vengono istanziati, producono una copia deldelle codicefunzioni utilizzate della oggettoclasse, e se tali classi contengono funzioni virtuali, produconovengono unareplicate copiaanche dellale ''vtable'' e dellale informazioni ''RTTI''.
Questi dati ingrandiscono eccessivamente il programma.
 
=== Annullamento dell'argomento di <code>delete</code> ===
Line 78 ⟶ 79:
D'altra parte, annullare il puntatore richiede una seppur piccolissima quantità di tempo.
 
Come tecnica di collaudo o di debugging, si può adottare laLa regola di annullare sempre il puntatore a cui è stato applicato l'operatore <code>delete</code> nellapuò generazioneessere diadottata unacome versionetecnica finalizzata aldi collaudo o di debugging, ma farlo anchesolamente nella generazione di una versione del codicesoftware destinata ad attività di produzionecollaudo èo un'inutiledi inefficienzadebugging.
 
=== Uso di deallocatori automatici ===
 
'''Non usare una libreria di [[w:Garbage collection|garbage-collection]] né gli smart-pointer condotati di reference-count (boost::come gli <code>shared_ptr</code> della libreria [http://www.boost.org/ Boost]), a meno che se ne dimostri l’opportunitàl'opportunità per il caso specifico.'''
 
La garbage collection, cioè il recupero automatico della memoria non più referenziata, fornisce la comodità di non doversi occupare della deallocazione della memoria, e previene i [[w:Memory leak|''memory leak'']].
Tale funzionalità non viene fornita dalla libreria standard, ma viene fornita da librerie non-standard.
Tuttavia, tale tecnica di gestione della memoria offre prestazioni peggiori della deallocazione esplicita (cioè chiamando l'operatore <code>delete</code>).
 
La libreria standard del C++98 contiene un solo smart-pointer, l'<code>auto_ptr</code>, che è efficiente. Altri smart-pointer sono forniti da librerie non-standard, come Boost, o verranno forniti dal C++0x.
Tra di essi, gli smart-pointer basati su reference-count, come lo <code>shared_ptr</code> di Boost, sono meno efficienti dei puntatori semplici, e quindi devono essere usati sonosolo nei casi in cui se ne dimostra la necessità.
In particolare, compilando con l'opzione di gestione del multithreading, tali funzionalitàpuntatori hanno pessime prestazioni nella creazione, distruzione e copia dei puntatori, in quanto devono garantire l'atomicitàla mutua esclusione delle operazioni.
 
Normalmente bisognerebbe, in fase di progettazione, cercare di assegnare ogni oggetto allocato dinamicamente ad un proprietario, cioè a un altro oggetto che lo possiede, nel senso che avrà la responsabilità di distruggerlo.
Solo quando tale assegnazione èrisulta difficile, in quanto più oggetti tendono a rimpallarsi la responsabilità di distruggere un l'oggetto, risulta opportuno usare uno smart-pointer con reference-count oppureper unagestire libreriatale di garbage-collectionoggetto.
 
=== Il modificatore <code>volatile</code> ===
 
'''Non definire sistematicamenteDefinisci <code>volatile</code> ognisolamente variabile,quelle ma solo quellevariabili che vengono modificate in modo asincrono da dispositivi hardware o da altripiù thread.'''
 
L'uso del modificatore <code>volatile</code> impedisce al compilatore di allocare una variabile in un registro.
Line 100 ⟶ 104:
 
[[Categoria:Ottimizzare C++|Costrutti che peggiorano le prestazioni]]
{{Avanzamento|75100%|2324 maggio 2008}}