2010-10-13 10 views
31

que he estado tratando de entender lo que realmente significa:¿Qué es el método en línea?

función en línea

En C++, una función miembro se define en la declaración de clase. (2) Una función llamada que el compilador reemplaza con el código real para la función. La palabra clave en línea se puede utilizar para insinuar el compilador para realizar la expansión en línea del cuerpo de un miembro o la función de no miembro .

línea

Para reemplazar una llamada de función con una copia del código de la función durante compilación.

Por ejemplo está escrito algo como:

Cuando un método es definitiva, puede ser inline.

aquí: http://www.roseindia.net/javatutorials/final_methods.shtml

¿Me puede dar un ejemplo o algo o básicamente me ayudará a entender lo que "puede ser inline" significa.

Gracias.

+1

Esto será de ayuda: http://java.sun.com/developer/onlineTraining/Programming/JDCBook/perf2.html#vm – codaddict

Respuesta

49

Inline es una optimización realizada por el compilador Java Just-In-Time.

Si usted tiene un método:

public int addPlusOne(int a, int b) { 
    return a + b + 1; 
} 

que llaman de esta manera:

public void testAddPlusOne() { 
    int v1 = addPlusOne(2, 5); 
    int v2 = addPlusOne(7, 13); 

    // do something with v1, v2 
} 

el compilador puede decidir reemplazar su llamada a la función con el cuerpo de la función, por lo que el resultado sería efectivamente se ve así:

public void testAddPlusOne() { 
    int v1 = 2 + 5 + 1; 
    int v2 = 7 + 13 + 1 

    // do something with v1, v2 
} 

El compilador hace esto para ahorrar la sobrecarga f en realidad hacer una llamada a función, lo que implicaría presionar cada parámetro en la pila.

Esto solo se puede hacer claramente para funciones no virtuales. Considere lo que sucedería si el método fuera anulado en una subclase y el tipo del objeto que contiene el método no se conoce hasta el tiempo de ejecución ... ¿cómo sabría el compilador qué código copiar: el cuerpo del método de la clase base o la subclase cuerpo del método? Dado que todos los métodos son virtuales por defecto en Java, puede marcar explícitamente aquellos que no pueden anularse como final (o ponerlos en una clase final). Esto ayudará al compilador a descubrir que el método nunca será anulado y que es seguro realizar la alineación. (Tenga en cuenta que el compilador a veces también puede hacer esta determinación para métodos no finales.)

Además, tenga en cuenta que la palabra puede en la cita. No se garantiza que los métodos finales sean alineables. Hay varias maneras en que puede garantizar que un método no sea capaz de estar en línea, pero no hay manera de forzar el compilador en línea. Casi siempre sabrá mejor que usted de todos modos cuando inline ayudará o perjudicará la velocidad del código resultante.

Consulte wikipedia para obtener una buena descripción de los beneficios y problemas.

+10

Buena respuesta, pero como nota: si tiene un método no final que * no * anula, un buen JIT puede descifrarlo e incluirlo de todos modos. Si luego carga una clase que la sobrescribe, puede deshacer la línea de entrada. – naiad

+0

Buen punto, lo agregué al cuerpo de respuestas. –

+0

Es muy explicativo, gracias por esta gran respuesta. – Tarik

9

Digamos que usted tiene una clase que tiene este aspecto:

public class Demo { 
    public void method() { 
     // call printMessage 
     printMessage(); 
    } 

    public void printMessage() { 
     System.out.println("Hello World"); 
    } 
} 

La llamada a printMessage podría ser "inline" de la siguiente manera:

public class Demo { 
    public void method() { 
     // call printMessage 
     System.out.println("Hello World"); // <-- inlined 
    } 

    public void printMessage() { 
     System.out.println("Hello World"); 
    } 
} 

(En realidad, esto no se hace en el nivel de Java (ni siquiera en el nivel de bytecode) pero durante la compilación JIT, pero el ejemplo anterior ilustra el concepto de inline.)

Ahora considere lo que sucedería si el método printMessage se sobrecargado por otra clase, así:

class SubDemo extends Demo { 
    public void printMessage() { 
     System.out.println("Something else"); 
    } 
} 

Ahora bien, si el compilador inlined la llamada a Demo.printMessage estaría pegado con System.out.println("Hello World"); que sería mal en caso de que el objeto era en realidad una instancia de SubDemo.

Sin embargo, si el método fue declarado final, este no sería en ningún caso el caso. Si el método es "final", significa que nunca se puede anular con una nueva definición, por lo tanto, es seguro alinearlo.

+0

También es una buena respuesta, pero como una nota copiada de otra respuesta: Si tiene una método no final que no anula, un buen JIT puede resolverlo e incluirlo de todos modos. Si luego carga una clase que la sobrescribe, puede deshacer la línea de entrada. – naiad

+0

Es muy explicativo, gracias por esta gran respuesta. – Tarik

10

Llamar a una función no es gratis. La máquina debe mantener un marco de pila para que pueda regresar a la sección de llamada del código cuando se completa la función llamada. Mantener la pila (incluidos los parámetros de la función de pasar en esta pila) lleva tiempo.

Cuando se alinea una función, el compilador reemplaza la llamada a la función con el código de la función para que se pueda evitar la penalización del rendimiento de una llamada a función en tiempo de ejecución. Esta es una de las compensaciones clásicas en programación: el código de tiempo de ejecución se vuelve un poco más grande (ocupa más memoria), pero funciona un poco más rápido.

+0

Gracias. En el primer párrafo, tienes mucha razón. – Tarik

Cuestiones relacionadas