Evitare il costo di una chiamata di funzione è solo metà della storia.
fare:
- utilizzare
inline
invece di#define
- funzioni molto piccole sono buoni candidati per
inline
: codice più veloce ed eseguibili più piccoli (più possibilità di rimanere nella cache del codice)
- la funzione è piccola e chiamata molto spesso
non:
- funzioni di grandi dimensioni: porta a eseguibili più grandi, che compromettono significativamente le prestazioni indipendentemente dall'esecuzione più rapida che risulta dal sovraccarico di chiamata
- funzioni incorporate associate a I / O
- la funzione viene usata raramente
- costruttori e distruttori: anche se vuoto, il compilatore genera codice per loro
- interruzione della compatibilità binaria durante lo sviluppo di librerie:
- incorporare una funzione esistente
- modificare una funzione inline o rendere non inline una funzione inline: la versione precedente della libreria chiama la vecchia implementazione
quando si sviluppa una libreria, al fine di rendere estensibile una classe in futuro è necessario:
- aggiungi un distruttore virtuale non in linea anche se il corpo è vuoto
- rendere tutti i costruttori non in linea
- scrivere implementazioni non in linea del costruttore della copia e dell'operatore di assegnazione a meno che la classe non possa essere copiata per valore
Ricorda che la inline
parola chiave è un suggerimento per il compilatore: il compilatore può decidere di non incorporare una funzione e può decidere di incorporare funzioni che non sono state contrassegnate inline
in primo luogo. In genere evito di contrassegnare la funzione inline
(a parte forse quando si scrivono funzioni molto piccole).
Per quanto riguarda le prestazioni, l'approccio saggio è (come sempre) il profilo dell'applicazione, quindi alla fine inline
un insieme di funzioni che rappresentano un collo di bottiglia.
Riferimenti:
EDIT: Bjarne Stroustrup, Il linguaggio di programmazione C ++:
Una funzione può essere definita come inline
. Per esempio:
inline int fac(int n)
{
return (n < 2) ? 1 : n * fac(n-1);
}
L' inline
identificatore indica al compilatore che dovrebbe tentare di generare il codice per una chiamata di fac()
inline anziché stabilire una volta il codice per la funzione e quindi chiamare attraverso il normale meccanismo di chiamata della funzione. Un compilatore intelligente può generare la costante 720
per una chiamata fac(6)
. La possibilità di funzioni inline reciprocamente ricorsive, funzioni inline che ricorrono o meno in base all'input, ecc., Rende impossibile garantire che ogni chiamata di una inline
funzione sia effettivamente incorporata. Il grado di intelligenza di un compilatore non può essere legiferato, quindi un compilatore potrebbe generare 720
, un altro 6 * fac(5)
e un altro ancora una chiamata non incorporata fac(6)
.
Per rendere possibile l'allineamento in assenza di funzioni di compilazione e collegamento insolitamente intelligenti, la definizione - e non solo la dichiarazione - di una funzione inline deve essere compresa (§9.2). Un inline
especifier non influisce sulla semantica di una funzione. In particolare, una funzione inline ha ancora un indirizzo univoco e quindi ha static
variabili (§7.1.2) di una funzione inline.
EDIT2: ISO-IEC 14882-1998, 7.1.2 Identificatori di funzione
Una dichiarazione di funzione (8.3.5, 9.3, 11.4) con un inline
identificatore dichiara una funzione incorporata. L'identificatore in linea indica all'implementazione che la sostituzione in linea del corpo della funzione nel punto di chiamata deve essere preferita al normale meccanismo di chiamata di funzione. Non è necessaria un'implementazione per eseguire questa sostituzione in linea al punto di chiamata; tuttavia, anche se questa sostituzione in linea viene omessa, le altre regole per le funzioni in linea definite da 7.1.2 devono comunque essere rispettate.
inline
è per il nuovo arrivato C ++ cosaCFLAGS
sono per il nuovo arrivato Gentoo: no, compilare-O3 -funroll-loops -finline-functions
non farà volare il tuo vecchio Pentium;)