C++ proporciona funciones en línea para reducir la sobrecarga de las llamadas a funciones. Una función en línea es una función que se expande en línea cuando se llama. Cuando se llama a la función en línea, el código completo de la función en línea se inserta o sustituye en el punto de la llamada a la función en línea. Esta sustitución la realiza el compilador de C++ en tiempo de compilación. Una función en línea puede aumentar la eficiencia si es pequeña.
Sintaxis:
inline return-type function-name(parameters) { // function code }>
Recuerde, la inserción es solo una solicitud al compilador, no un comando. El compilador puede ignorar la solicitud de inserción.
El compilador no puede realizar la inserción en circunstancias tales como:
- Si una función contiene un bucle. ( para, mientras y hacer-mientras )
- Si una función contiene variables estáticas.
- Si una función es recursiva.
- Si el tipo de retorno de una función no es nulo y la declaración de retorno no existe en el cuerpo de una función.
- Si una función contiene una instrucción switch o goto.
¿Por qué se utilizan funciones en línea?
Cuando el programa ejecuta la instrucción de llamada a la función, la CPU almacena la dirección de memoria de la instrucción que sigue a la llamada a la función, copia los argumentos de la función en la pila y finalmente transfiere el control a la función especificada. Luego, la CPU ejecuta el código de función, almacena el valor de retorno de la función en una ubicación/registro de memoria predefinido y devuelve el control a la función que llama. Esto puede convertirse en una sobrecarga si el tiempo de ejecución de la función es menor que el tiempo de cambio de la función que llama a la función llamada (llamada).
Para funciones que son grandes y/o realizan tareas complejas, la sobrecarga de la llamada a la función suele ser insignificante en comparación con la cantidad de tiempo que tarda la función en ejecutarse. Sin embargo, para funciones pequeñas y de uso común, el tiempo necesario para realizar la llamada a la función suele ser mucho mayor que el tiempo necesario para ejecutar realmente el código de la función. Esta sobrecarga ocurre para funciones pequeñas porque el tiempo de ejecución de una función pequeña es menor que el tiempo de conmutación.
Funciones en línea Ventajas:
- La sobrecarga de llamadas a funciones no ocurre.
- También ahorra la sobrecarga de las variables push/pop en la pila cuando se llama a una función.
- También ahorra la sobrecarga de una llamada de devolución desde una función.
- Cuando inserta una función, puede permitir que el compilador realice una optimización específica del contexto en el cuerpo de la función. Estas optimizaciones no son posibles para llamadas a funciones normales. Se pueden obtener otras optimizaciones considerando los flujos del contexto de llamada y del contexto llamado.
- Una función en línea puede ser útil (si es pequeña) para sistemas integrados porque en línea puede generar menos código que la función llamada preámbulo y retorno.
Desventajas de la función en línea:
- Las variables agregadas de la función en línea consumen registros adicionales. Después de la función en línea, si el número de variable que va a utilizar el registro aumenta, pueden crear una sobrecarga en la utilización de recursos de la variable de registro. Esto significa que cuando el cuerpo de la función en línea se sustituye en el punto de la llamada a la función, también se inserta el número total de variables utilizadas por la función. Por lo tanto, también aumentará la cantidad de registros que se utilizarán para las variables. Entonces, si después de incluir la función los números de variables aumentan drásticamente, seguramente causará una sobrecarga en la utilización del registro.
- Si utiliza demasiadas funciones en línea, el tamaño del archivo binario ejecutable será grande debido a la duplicación del mismo código.
- Demasiada inserción también puede reducir la tasa de aciertos de la caché de instrucciones, reduciendo así la velocidad de recuperación de instrucciones de la memoria caché a la de la memoria primaria.
- La función en línea puede aumentar la sobrecarga del tiempo de compilación si alguien cambia el código dentro de la función en línea, entonces se debe volver a compilar toda la ubicación de llamada porque se requeriría que el compilador reemplace todo el código una vez más para reflejar los cambios; de lo contrario, continuará con el antiguo. funcionalidad.
- Es posible que las funciones en línea no sean útiles para muchos sistemas integrados. Porque en los sistemas integrados el tamaño del código es más importante que la velocidad.
- Las funciones en línea pueden provocar alteraciones porque la incorporación en línea puede aumentar el tamaño del archivo ejecutable binario. La destrucción de la memoria hace que el rendimiento de la computadora se degrade. El siguiente programa demuestra el uso de la función en línea.
Ejemplo:
C++
#include> using> namespace> std;> inline> int> cube(>int> s) {>return> s * s * s; }> int> main()> {> >cout <<>'The cube of 3 is: '> << cube(3) <<>'
'>;> >return> 0;> }> |
>
>Producción
The cube of 3 is: 27>
Funciones y clases en línea
También es posible definir la función en línea dentro de la clase. De hecho, todas las funciones definidas dentro de la clase están implícitamente en línea. Por lo tanto, aquí también se aplican todas las restricciones de las funciones en línea. Si necesita declarar explícitamente una función en línea en la clase, simplemente declare la función dentro de la clase y defínala fuera de la clase usando la palabra clave en línea.
Sintaxis:
class S { public: inline int square(int s) // redundant use of inline { // this function is automatically inline // function body } };> El estilo anterior se considera un mal estilo de programación. El mejor estilo de programación es simplemente escribir el prototipo de la función dentro de la clase y especificarlo en línea en la definición de la función.
Por ejemplo:
class S { public: int square(int s); // declare the function }; inline int S::square(int s) // use inline prefix { }> Ejemplo:
C++
// C++ Program to demonstrate inline functions and classes> #include> using> namespace> std;> class> operation {> >int> a, b, add, sub, mul;> >float> div>;> public>:> >void> get();> >void> sum();> >void> difference();> >void> product();> >void> division();> };> inline> void> operation ::get()> {> >cout <<>'Enter first value:'>;> >cin>>a;> >cout <<>'Enter second value:'>;> >cin>>b;> }> inline> void> operation ::sum()> {> >add = a + b;> >cout <<>'Addition of two numbers: '> << a + b <<>'
'>;> }> inline> void> operation ::difference()> {> >sub = a - b;> >cout <<>'Difference of two numbers: '> << a - b <<>'
'>;> }> inline> void> operation ::product()> {> >mul = a * b;> >cout <<>'Product of two numbers: '> << a * b <<>'
'>;> }> inline> void> operation ::division()> {> >div> = a / b;> >cout <<>'Division of two numbers: '> << a / b <<>'
'>;> }> int> main()> {> >cout <<>'Program using inline function
'>;> >operation s;> >s.get();> >s.sum();> >s.difference();> >s.product();> >s.division();> >return> 0;> }> |
>
isletra java
>
Producción:
Enter first value: 45 Enter second value: 15 Addition of two numbers: 60 Difference of two numbers: 30 Product of two numbers: 675 Division of two numbers: 3>
¿Qué le pasa a la macro?
Los lectores familiarizados con el lenguaje C saben que el lenguaje C usa macro. El preprocesador reemplaza todas las llamadas de macro directamente dentro del código de macro. Se recomienda utilizar siempre la función en línea en lugar de la macro. Según el Dr. Bjarne Stroustrup, el creador de C++ las macros casi nunca son necesarias en C++ y son propensas a errores. Existen algunos problemas con el uso de macros en C++. Macro no puede acceder a miembros privados de la clase. Las macros parecen llamadas a funciones, pero en realidad no lo son.
Ejemplo:
C++
// C++ Program to demonstrate working of macro> #include> using> namespace> std;> class> S {> >int> m;> public>:> >// error> #define MAC(S::m)> };> |
>
>
Producción:
Error: '::' may not appear in macro parameter list #define MAC(S::m)>
El compilador de C++ verifica los tipos de argumentos de las funciones en línea y las conversiones necesarias se realizan correctamente. La macro del preprocesador no es capaz de hacer esto. Otra cosa es que las macros las gestiona el preprocesador y las funciones en línea las gestiona el compilador de C++. Recuerde: es cierto que todas las funciones definidas dentro de la clase están implícitamente en línea y el compilador de C++ realizará llamadas en línea de estas funciones, pero el compilador de C++ no puede realizar llamadas en línea si la función es virtual. El motivo de la llamada a una función virtual se resuelve en tiempo de ejecución en lugar de en tiempo de compilación. Virtual significa esperar hasta el tiempo de ejecución y en línea significa durante la compilación. Si el compilador no sabe qué función se llamará, ¿cómo puede realizar la inserción en línea? Otra cosa para recordar es que solo es útil hacer que la función esté en línea si el tiempo empleado durante una llamada de función es mayor en comparación con el tiempo de ejecución del cuerpo de la función.
Un ejemplo donde la función en línea no tiene ningún efecto:
inline void show() { cout << 'value of S = ' << S << endl; }> La función anterior tarda relativamente mucho en ejecutarse. En general, una función que realiza una operación de entrada-salida (E/S) no debe definirse como en línea porque requiere una cantidad de tiempo considerable. Técnicamente, la inserción de la función show() tiene un valor limitado porque la cantidad de tiempo que tomará la declaración de E/S excede con creces la sobrecarga de una llamada de función. Dependiendo del compilador que esté utilizando, el compilador puede mostrarle una advertencia si la función no se expande en línea.
Los lenguajes de programación como Java y C# no admiten funciones en línea. Pero en Java, el compilador puede realizar la inserción cuando se llama al método final pequeño porque las subclases no pueden anular los métodos finales y la llamada a un método final se resuelve en el momento de la compilación.
En C#, el compilador JIT también puede optimizar el código incorporando pequeñas llamadas a funciones (como reemplazar el cuerpo de una pequeña función cuando se llama en un bucle). Lo último que hay que tener en cuenta es que las funciones en línea son una característica valiosa de C++. El uso apropiado de funciones en línea puede mejorar el rendimiento, pero si las funciones en línea se usan arbitrariamente, no pueden proporcionar mejores resultados. En otras palabras, no esperes un mejor desempeño del programa. No hagas todas las funciones en línea. Es mejor mantener las funciones en línea lo más pequeñas posible.