¿Cuáles son los beneficios de las funciones en línea?

Resuelto Lennie De Villiers asked hace 15 años • 14 respuestas

¿Cuáles son las ventajas/desventajas de usar funciones en línea en C++? Veo que solo aumenta el rendimiento del código que genera el compilador, pero con los compiladores optimizados de hoy, CPU rápidas, memoria enorme, etc. (no como en 1980 <donde la memoria era escasa y todo tenía que caber en 100 KB de memoria), ¿qué ¿Qué ventajas tienen realmente hoy en día?

Lennie De Villiers avatar Sep 28 '08 20:09 Lennie De Villiers
Aceptado

Ventajas

  • Al incluir su código donde es necesario, su programa dedicará menos tiempo a la llamada a la función y a las partes devueltas. Se supone que hace que su código vaya más rápido, incluso cuando crece (ver más abajo). La incorporación de accesores triviales podría ser un ejemplo de incorporación eficaz.
  • Al marcarlo como en línea, puede colocar una definición de función en un archivo de encabezado (es decir, puede incluirse en varias unidades de compilación, sin que el vinculador se queje).

Desventajas

  • Puede agrandar su código (es decir, si usa en línea para funciones no triviales). Como tal, podría provocar paginación y anular optimizaciones del compilador.
  • Rompe ligeramente su encapsulación porque expone el procesamiento interno de su objeto (pero todos los miembros "privados" también lo harían). Esto significa que no debe utilizar la inserción en un patrón PImpl.
  • Rompe ligeramente su encapsulación 2: la inserción de C++ se resuelve en el momento de la compilación. Lo que significa que si cambia el código de la función incorporada, deberá volver a compilar todo el código que la utiliza para asegurarse de que se actualice (por la misma razón, evito los valores predeterminados para los parámetros de la función).
  • Cuando se usa en un encabezado, hace que su archivo de encabezado sea más grande y, por lo tanto, diluirá información interesante (como la lista de métodos de una clase) con código que no le interesa al usuario (esta es la razón por la que declaro funciones insertadas dentro de un clase, pero la definirá en un encabezado después del cuerpo de la clase, y nunca dentro del cuerpo de la clase).

Magia en línea

  • El compilador puede o no incorporar las funciones que usted marcó como incorporadas; También puede decidir incorporar funciones que no estén marcadas como incorporadas en el momento de la compilación o del enlace.
  • Inline funciona como copiar y pegar controlado por el compilador, lo cual es bastante diferente de una macro de preprocesador: la macro se insertará a la fuerza, contaminará todos los espacios de nombres y el código, no será fácilmente depurable y se realizará incluso si el compilador lo hubiera considerado ineficiente.
  • Cada método de una clase definido dentro del cuerpo de la clase misma se considera "integrado" (incluso si el compilador aún puede decidir no incluirlo).
  • No se supone que los métodos virtuales sean inlinables. Aún así, a veces, cuando el compilador puede saber con seguridad el tipo de objeto (es decir, el objeto fue declarado y construido dentro del mismo cuerpo de función), incluso una función virtual estará incorporada porque el compilador sabe exactamente el tipo de objeto.
  • Los métodos/funciones de plantilla no siempre están integrados (su presencia en un encabezado no los integrará automáticamente).
  • El siguiente paso después de "en línea" es la metaprogramación de plantillas. Es decir, al "incorporar" su código en el momento de la compilación, a veces, el compilador puede deducir el resultado final de una función... Por lo tanto, un algoritmo complejo a veces puede reducirse a una especie de return 42 ;declaración. Esto es para mí una línea extrema . Ocurre raramente en la vida real, prolonga el tiempo de compilación, no inflará su código y lo hará más rápido. Pero como el grial, no intentes aplicarlo en todas partes porque la mayoría del procesamiento no se puede resolver de esta manera... Aún así, esto es genial de todos modos...
    :-p
paercebal avatar Sep 28 '2008 14:09 paercebal

Las funciones en línea son más rápidas porque no es necesario insertar y sacar elementos de la pila, como parámetros y la dirección del remitente; sin embargo, hace que su binario sea un poco más grande.

¿Hace una diferencia significativa? Para la mayoría, no se nota lo suficiente en hardware moderno. Pero puede marcar la diferencia, lo cual es suficiente para algunas personas.

Marcar algo en línea no le garantiza que estará en línea. Es solo una sugerencia para el compilador. A veces no es posible, como cuando tienes una función virtual o cuando hay recursividad involucrada. Y a veces el compilador simplemente decide no usarlo.

Podría ver una situación como esta haciendo una diferencia detectable:

inline int aplusb_pow2(int a, int b) {
  return (a + b)*(a + b) ;
}

for(int a = 0; a < 900000; ++a)
    for(int b = 0; b < 900000; ++b)
        aplusb_pow2(a, b);
Brian R. Bondy avatar Sep 28 '2008 13:09 Brian R. Bondy

En C y C++ arcaicos, inlinees como register: una sugerencia (nada más que una sugerencia) al compilador sobre una posible optimización.

En C++ moderno, inlinele dice al vinculador que, si se encuentran múltiples definiciones (no declaraciones) en diferentes unidades de traducción, todas son iguales y el vinculador puede conservar una libremente y descartar todas las demás.

inlinees obligatorio si una función (no importa cuán compleja o "lineal") se define en un archivo de encabezado, para permitir que múltiples fuentes la incluyan sin que el vinculador emita un error de "definición múltiple".

Las funciones miembro definidas dentro de una clase están "en línea" de forma predeterminada, al igual que las funciones de plantilla (a diferencia de las funciones globales).

//fileA.h
inline void afunc()
{ std::cout << "this is afunc" << std::endl; }

//file1.cpp
#include "fileA.h"
void acall()
{ afunc(); }

//main.cpp
#include "fileA.h"
void acall();

int main()
{ 
   afunc(); 
   acall();
}

//output
this is afunc
this is afunc

Tenga en cuenta la inclusión de fileA.h en dos archivos .cpp, lo que da como resultado dos instancias de afunc(). El vinculador descartará uno de ellos. Si no inlinese especifica, el vinculador se quejará.

Emilio Garavaglia avatar Sep 14 '2011 14:09 Emilio Garavaglia

La inserción es una sugerencia para el compilador que puede ignorar libremente. Es ideal para pequeños fragmentos de código.

Si su función está integrada, básicamente se inserta en el código donde se realiza la llamada a la función, en lugar de llamar a una función separada. Esto puede ayudar con la velocidad, ya que no es necesario realizar la llamada real.

También ayuda a las CPU con la canalización, ya que no tienen que recargar la canalización con nuevas instrucciones causadas por una llamada.

La única desventaja es el posible aumento del tamaño binario pero, mientras las funciones sean pequeñas, esto no importará demasiado.

Tiendo a dejar este tipo de decisiones a los compiladores hoy en día (bueno, a los inteligentes de todos modos). Las personas que los escribieron tienden a tener un conocimiento mucho más detallado de las arquitecturas subyacentes.

paxdiablo avatar Sep 28 '2008 13:09 paxdiablo

La función en línea es la técnica de optimización utilizada por los compiladores. Uno puede simplemente anteponer una palabra clave en línea al prototipo de función para crear una función en línea. La función en línea indica al compilador que inserte el cuerpo completo de la función dondequiera que se use esa función en el código.

Ventajas: -

  1. No requiere sobrecarga de llamadas a funciones.

  2. También ahorra la sobrecarga de las variables push/pop en la pila, mientras se llama a la función.

  3. También ahorra la sobrecarga de la llamada de devolución desde una función.

  4. Aumenta la localidad de referencia mediante el uso de caché de instrucciones.

  5. Después del compilador en línea, también se puede aplicar la optimización intraprocedimiento si se especifica. Este es el más importante, de esta manera el compilador ahora puede centrarse en la eliminación del código muerto, puede dar más énfasis a la predicción de ramas, la eliminación de variables de inducción, etc.

Para obtener más información al respecto, puede seguir este enlace http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html

TSS avatar Sep 14 '2011 03:09 TSS