Evitar el costo de una llamada a funciones es solo la mitad de la historia.
hacer:
- usar en
inline
lugar de#define
- las funciones muy pequeñas son buenas candidatas para
inline
: código más rápido y ejecutables más pequeños (más posibilidades de permanecer en el caché de código)
- la función es pequeña y se llama con mucha frecuencia
no:
- funciones grandes: conduce a ejecutables más grandes, lo que perjudica significativamente el rendimiento independientemente de la ejecución más rápida que resulta de la sobrecarga de llamadas
- funciones en línea que están vinculadas a E / S
- la función rara vez se usa
- constructores y destructores: incluso cuando está vacío, el compilador genera código para ellos
- romper la compatibilidad binaria al desarrollar bibliotecas:
- en línea una función existente
- cambiar una función en línea o hacer que una función en línea no esté en línea: la versión anterior de la biblioteca llama a la implementación anterior
al desarrollar una biblioteca, para que una clase sea extensible en el futuro, debe:
- agregar destructor virtual no en línea incluso si el cuerpo está vacío
- hacer que todos los constructores no estén en línea
- escribir implementaciones no en línea del constructor de copia y el operador de asignación a menos que la clase no se pueda copiar por valor
Recuerde que la inline
palabra clave es una pista para el compilador: el compilador puede decidir no incluir una función en línea y puede decidir incluir funciones que no se marcaron inline
en primer lugar. En general, evito marcar la función inline
(aparte, tal vez cuando escribo funciones muy muy pequeñas).
En cuanto al rendimiento, el enfoque inteligente es (como siempre) perfilar la aplicación, y finalmente inline
un conjunto de funciones que representan un cuello de botella.
Referencias
EDITAR: Bjarne Stroustrup, El lenguaje de programación C ++:
Una función se puede definir para ser inline
. Por ejemplo:
inline int fac(int n)
{
return (n < 2) ? 1 : n * fac(n-1);
}
El inline
especificador es una pista para el compilador de que debería intentar generar código para una llamada en fac()
línea en lugar de establecer el código para la función una vez y luego llamar a través del mecanismo habitual de llamada de función. Un compilador inteligente puede generar la constante 720
para una llamada fac(6)
. La posibilidad de funciones en línea recursivas mutuamente, funciones en línea que se repiten o no dependen de la entrada, etc., hace que sea imposible garantizar que cada llamada de una inline
función esté realmente en línea. El grado de inteligencia de un compilador no se puede legislar, por lo que un compilador puede generar 720
, otro 6 * fac(5)
, y otro más una llamada no en línea fac(6)
.
Para hacer posible la alineación en ausencia de facilidades de compilación y enlace inusualmente inteligentes, la definición, y no solo la declaración, de una función en línea debe estar dentro del alcance (§9.2). Un inline
especificador no afecta la semántica de una función. En particular, una función en línea todavía tiene una dirección única y también tiene static
variables (§7.1.2) de una función en línea.
EDIT2: ISO-IEC 14882-1998, 7.1.2 Especificadores de funciones
Una declaración de función (8.3.5, 9.3, 11.4) con un inline
especificador declara una función en línea. El especificador en línea indica a la implementación que la sustitución en línea del cuerpo de la función en el punto de llamada debe preferirse al mecanismo habitual de llamada a la función. No se requiere una implementación para realizar esta sustitución en línea en el punto de llamada; sin embargo, incluso si se omite esta sustitución en línea, se seguirán respetando las otras reglas para las funciones en línea definidas en 7.1.2.
inline
es para el recién llegado de C ++ lo queCFLAGS
es para el recién llegado de Gentoo: no, compilar con-O3 -funroll-loops -finline-functions
no hará volar su antiguo Pentium;)