Evitar el costo de una llamada a funciones es solo la mitad de la historia.
hacer:
- usar en
inlinelugar 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 inlinepalabra 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 inlineen 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 inlineun 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 inlineespecificador 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 720para 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 inlinefunció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 inlineespecificador 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 staticvariables (§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 inlineespecificador 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.
inlinees para el recién llegado de C ++ lo queCFLAGSes para el recién llegado de Gentoo: no, compilar con-O3 -funroll-loops -finline-functionsno hará volar su antiguo Pentium;)