Je ne connais pas vraiment les internes du compilateur et les optimisations JIT, mais j'essaie généralement d'utiliser le "bon sens" pour deviner ce qui pourrait être optimisé et ce qui ne le pourrait pas. Donc là j'écrivais une méthode de test unitaire simple aujourd'hui:Comment écrire (tester) du code qui ne sera pas optimisé par le compilateur/JIT?
@Test // [Test] in C#
public void testDefaultConstructor() {
new MyObject();
}
Cette méthode est réellement tout ce dont j'ai besoin. Il vérifie que le constructeur par défaut existe et s'exécute sans exceptions.
Mais j'ai commencé à réfléchir à l'effet des optimisations du compilateur/JIT. Le compilateur/JIT pourrait-il optimiser cette méthode en éliminant complètement l'instruction new MyObject();
? Bien sûr, il faudrait déterminer que le graphe d'appel n'a pas d'effets secondaires sur les autres objets, ce qui est le cas typique d'un constructeur normal qui initialise simplement l'état interne de l'objet.
Je présume que seul le JIT serait autorisé à effectuer une telle optimisation. Cela signifie probablement que ce n'est pas quelque chose dont je devrais m'inquiéter, car la méthode de test n'est effectuée qu'une seule fois. Mes hypothèses sont-elles correctes?
Néanmoins, j'essaie de penser au sujet général. Quand j'ai pensé à comment empêcher cette méthode d'être optimisée, j'ai pensé que je pouvais assertTrue(new MyObject().toString() != null)
, mais cela dépend beaucoup de l'implémentation réelle de la méthode toString()
, et même alors, le JIT peut déterminer que la méthode toString()
retourne toujours un non-null chaîne (par exemple, si en réalité Object.toString()
est appelée), et ainsi optimiser la branche entière. Donc, cette façon ne fonctionnerait pas.
Je sais que dans C# je peux utiliser [MethodImpl(MethodImplOptions.NoOptimization)]
, mais ce n'est pas ce que je cherche réellement. J'espère trouver une façon (indépendante de la langue) de m'assurer que certaines parties spécifiques de mon code fonctionneront réellement comme je le souhaite, sans que le JIT n'interfère dans ce processus.
De plus, y a-t-il des cas d'optimisation typiques que je devrais connaître lors de la création de mes tests unitaires?
Merci beaucoup!
Merci. Je me demande pourquoi le JIT se comporte de cette façon? Si une allocation d'objet est inutile (comme cela peut être déterminé par l'analyse statique dans certains cas), pourquoi le JIT ne l'optimiserait-il pas? –
Je peux maintenant penser à un cas de coin, mais je pense que c'est assez rare.Si l'allocation d'objet a été faite par exemple pour s'assurer que suffisamment de mémoire est disponible pour un ou plusieurs autres objets (et même en s'assurant qu'il n'y aura pas de pagination), l'optimisation invaliderait l'hypothèse. –
Il est nécessaire de laisser la machine virtuelle Java (JVM) dans un état cohérent avec l'exécution du code de programme dans la JVM conformément au modèle de mémoire Java. Il n'est pas nécessaire d'exécuter réellement un code spécifique ou d'allouer de la mémoire dans le cas où le JIT peut prouver que le code n'a aucun effet sur l'état de programme observable. –