No sé mucho sobre los aspectos internos del compilador y las optimizaciones de JIT, pero generalmente trato de usar el "sentido común" para adivinar qué podría optimizarse y qué no. Así que estaba escribiendo un método de prueba unitaria simple hoy:¿Cómo escribo (prueba) el código que no será optimizado por el compilador/JIT?
@Test // [Test] in C#
public void testDefaultConstructor() {
new MyObject();
}
Este método es en realidad todo lo que necesito. Comprueba que el constructor predeterminado existe y se ejecuta sin excepciones.
Pero luego comencé a pensar en el efecto de las optimizaciones del compilador/JIT. ¿Podría el compilador/JIT optimizar este método eliminando por completo la declaración new MyObject();
? Por supuesto, necesitaría determinar que el gráfico de llamadas no tiene efectos secundarios para otros objetos, que es el caso típico de un constructor normal que simplemente inicializa el estado interno del objeto.
Supongo que solo el JIT podría realizar dicha optimización. Esto probablemente significa que no es algo de lo que deba preocuparme, porque el método de prueba se realiza solo una vez. ¿Son mis suposiciones correctas?
Sin embargo, estoy tratando de pensar sobre el tema general. Cuando pensé en cómo evitar que este método se optimice, pensé que podría assertTrue(new MyObject().toString() != null)
, pero esto depende mucho de la implementación real del método toString()
, e incluso entonces, el JIT puede determinar que el método toString()
siempre devuelve un método no nulo cadena (por ejemplo, si realmente se está llamando al Object.toString()
), y así optimizar toda la rama. Entonces esta forma no funcionaría.
Sé que en C# puedo usar [MethodImpl(MethodImplOptions.NoOptimization)]
, pero esto no es lo que realmente estoy buscando. Espero encontrar una forma (independiente del lenguaje) de asegurarme de que algunas partes específicas de mi código se ejecutarán realmente como espero, sin que el JIT interfiera en este proceso.
Además, ¿hay algún caso típico de optimización que deba tener en cuenta al crear mis pruebas unitarias?
¡Muchas gracias!
Gracias. Me pregunto por qué el JIT se comporta de esta manera? Si la asignación de un objeto es inútil (como en realidad puede determinarse por análisis estático en algunos casos), ¿por qué el JIT no lo optimizaría? –
Ahora puedo pensar en un caso de esquina, pero creo que es bastante raro.Si la asignación de objetos se realizó, por ejemplo, para garantizar que haya suficiente memoria disponible para algunos otros objetos (e incluso para asegurarse de que no haya paginación), la optimización invalidaría la suposición. –
Se requiere dejar Java Virtual Machine (JVM) en un estado consistente con haber ejecutado el código del programa en la JVM de acuerdo con el Modelo de memoria de Java. No es necesario ejecutar realmente ningún código específico ni asignar memoria en el caso de que el JIT pueda demostrar que el código no tiene ningún efecto en el estado del programa observable. –