¿Existe un concepto de funciones en línea en Java, o se reemplazó por algo más? Si lo hay, ¿cómo se usa? Escuché eso public
, static
y los final
métodos son las funciones en línea. ¿Podemos crear nuestra propia función en línea?
¿Existe un concepto de funciones en línea en Java, o se reemplazó por algo más? Si lo hay, ¿cómo se usa? Escuché eso public
, static
y los final
métodos son las funciones en línea. ¿Podemos crear nuestra propia función en línea?
Respuestas:
En Java, las optimizaciones generalmente se realizan a nivel de JVM. En tiempo de ejecución, la JVM realiza un análisis "complicado" para determinar qué métodos incorporar. Puede ser agresivo en la alineación, y Hotspot JVM en realidad puede incorporar métodos no finales en línea.
Los compiladores de Java casi nunca integran ninguna llamada de método (la JVM hace todo eso en tiempo de ejecución). Ellos compilan en línea constantes de tiempo (por ejemplo, valores primitivos estáticos finales). Pero no métodos.
Para más recursos:
Artículo: El motor de rendimiento de Java HotSpot: ejemplo de inserción de métodos
Wiki: incluido en OpenJDK , no está completamente poblado pero contiene enlaces a discusiones útiles.
No, no hay una función en línea en java. Sí, puede usar un método estático público en cualquier parte del código cuando se coloca en una clase pública. El compilador de Java puede hacer una expansión en línea en un método estático o final, pero eso no está garantizado.
Normalmente, el compilador realiza estas optimizaciones de código en combinación con JVM / JIT / HotSpot para los segmentos de código que se utilizan con mucha frecuencia. Además, otros conceptos de optimización como la declaración de registro de parámetros no se conocen en java.
Las optimizaciones no se pueden forzar mediante una declaración en java, sino que se realizan mediante el compilador y JIT. En muchos otros lenguajes, estas declaraciones a menudo son solo sugerencias del compilador (puede declarar más parámetros de registro que los que tiene el procesador, el resto se ignora).
Declarar los métodos Java estáticos, finales o privados también son sugerencias para el compilador. Debería usarlo, pero sin garantías. El rendimiento de Java es dinámico, no estático. La primera llamada a un sistema siempre es lenta debido a la carga de clases. Las siguientes llamadas son más rápidas, pero dependiendo de la memoria y el tiempo de ejecución, las llamadas más comunes se optimizan dentro del sistema en ejecución, por lo que un servidor puede volverse más rápido durante el tiempo de ejecución.
final
hacer ningún impacto en procesos en línea JIT
Java no proporciona una forma de sugerir manualmente que un método debe estar insertado. Como dice @notnoop en los comentarios, la JVM suele realizar la inserción en el momento de la ejecución.
jdk.internal.vm.annotation.ForceInline
Lo que dijiste arriba es correcto. A veces, los métodos finales se crean como en línea, pero no hay otra forma de crear explícitamente una función en línea en java.
final
ni siquiera hace ninguna diferencia en cuanto a si el método está integrado o no.
Ejemplo de la vida real:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
Luego, en otras clases, puedo salir si el código ha expirado. Si hago referencia a la variable EXPIRED_ON de otra clase, la constante está en línea con el código de bytes, lo que dificulta rastrear todos los lugares en el código que verifica la fecha de vencimiento. Sin embargo, si las otras clases invocan el método isExpired (), se llama al método real, lo que significa que un pirata informático podría reemplazar el método isExpired por otro que siempre devuelve falso.
Estoy de acuerdo en que sería muy bueno forzar a un compilador a incorporar el método final estático a todas las clases que lo hacen referencia. En ese caso, ni siquiera necesita incluir la clase Control, ya que no sería necesaria en tiempo de ejecución.
Según mi investigación, esto no se puede hacer. Quizás algunas herramientas de Obfuscator puedan hacer esto, o podría modificar su proceso de compilación para editar las fuentes antes de compilar.
En cuanto a probar si el método de la clase de control se coloca en línea con otra clase durante la compilación, intente ejecutar la otra clase sin la clase Control en la ruta de clases.
Bueno, hay métodos que podrían llamarse métodos "en línea" en Java, pero dependiendo del archivo jvm. Después de la compilación, si el código de máquina del método tiene menos de 35 bytes, se transferirá a un método en línea de inmediato; si el código de máquina del método tiene menos de 325 bytes, se puede transferir a un método en línea, según el jvm.
entonces, parece que no los hay, pero puede usar esta solución usando guava o una implementación de clase de función equivalente, porque esa clase es extremadamente simple, por ejemplo:
assert false : new com.google.common.base.Function<Void,String>(){
@Override public String apply(Void input) {
//your complex code go here
return "weird message";
}}.apply(null);
sí, este es un código muerto solo para ejemplificar cómo crear un bloque de código complejo (dentro de {}) para hacer algo tan específico que no debería molestarnos en crear ningún método para ello, también conocido como en línea.