Existe-t-il un concept de fonctions inline en Java, ou remplace-t-il autre chose? Si c'est le cas, comment est-il utilisé? J'ai entendu dire que les méthodes public
, static
et final
sont les fonctions en ligne. Pouvons-nous créer notre propre fonction inline?
En Java, les optimisations sont généralement effectuées au niveau de la JVM. Au moment de l'exécution, la machine virtuelle Java effectue une analyse "complexe" pour déterminer les méthodes à intégrer. Elle peut être agressive en ligne et la machine virtuelle Hotspot peut en réalité intégrer des méthodes non finales.
Les compilateurs Java ne lient presque jamais aucun appel de méthode (la JVM effectue tout cela au moment de l'exécution). Ils font des constantes de temps de compilation en ligne (par exemple, des valeurs primitives statiques finales). Mais pas les méthodes.
Pour plus de ressources:
Article: Le moteur de performance Java HotSpot: Exemple d'inclusion de méthode
Wiki: Inlining in OpenJDK , pas complètement rempli, mais contient des liens vers des discussions utiles.
Java ne fournit pas un moyen de suggérer manuellement qu'une méthode doit être en ligne. Comme @notnoop le dit dans les commentaires, l’installation est généralement effectuée par la machine virtuelle au moment de l’exécution.
Non, il n'y a pas de fonction inline en Java. Oui, vous pouvez utiliser une méthode statique publique n'importe où dans le code lorsque vous êtes placé dans une classe publique. Le compilateur Java peut faire développement en ligne sur une méthode statique ou finale, mais cela n’est pas garanti.
En règle générale, le compilateur effectue ces optimisations de code en combinaison avec JVM/JIT/HotSpot pour les segments de code utilisés très souvent. De plus, d'autres concepts d'optimisation, tels que la déclaration de paramètres par le registre, ne sont pas connus en Java.
Les optimisations ne peuvent pas être forcées par déclaration en Java, mais par compilateur et JIT. Dans de nombreux autres langages, ces déclarations ne sont souvent que des indications du compilateur (vous pouvez déclarer plus de paramètres de registre que le processeur, le reste est ignoré).
Déclarer les méthodes Java static, final ou private sont également des astuces pour le compilateur. Vous devriez l'utiliser, mais pas de garanties. Les performances Java sont dynamiques et non statiques. Le premier appel à un système est toujours lent en raison du chargement de la classe. Les prochains appels sont plus rapides, mais en fonction de la mémoire et de l'exécution, les appels les plus courants sont optimisés avec le système en cours d'exécution, de sorte qu'un serveur peut devenir plus rapide pendant l'exécution!
Ce que vous avez dit ci-dessus est correct. Parfois, les méthodes finales sont créées en tant qu'inline, mais il n'existe pas d'autre moyen de créer explicitement une fonction inline en Java.
Exemple concret:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
Ensuite, dans d'autres classes, je peux quitter si le code a expiré. Si je référence la variable EXPIRED_ON d'une autre classe, la constante est intégrée au code d'octet, ce qui rend très difficile la recherche de tous les emplacements du code qui vérifient la date d'expiration. Cependant, si les autres classes invoquent la méthode isExpired (), la méthode elle-même est appelée, ce qui signifie qu'un pirate informatique pourrait remplacer la méthode isExpired par une autre qui renvoie toujours la valeur false.
Je conviens qu’il serait très agréable de forcer un compilateur à intégrer la méthode finale statique à toutes les classes qui la référencent. Dans ce cas, vous n'avez même pas besoin d'inclure la classe Control, car elle ne serait pas nécessaire au moment de l'exécution.
D'après mes recherches, cela ne peut être fait. Peut-être que certains outils d'obscurcissement peuvent le faire, ou vous pouvez modifier votre processus de construction pour éditer les sources avant la compilation.
Pour ce qui est de prouver que la méthode de la classe de contrôle est placée en ligne dans une autre classe pendant la compilation, essayez d’exécuter l’autre classe sans la classe Control dans le chemin de classe.
Eh bien, il existe des méthodes qui pourraient être appelées méthodes "inline" en Java, mais cela dépend du jvm. Après la compilation, si le code machine de la méthode est inférieur à 35 octets, il sera immédiatement transféré vers une méthode en ligne. Si le code machine de la méthode est inférieur à 325 octets, il peut être transféré dans une méthode en ligne, en fonction du jvm.
donc, il semble n'y avoir aucune solution, mais vous pouvez utiliser cette solution de contournement à l'aide de goyave ou d'une implémentation équivalente de la classe Function, car cette classe est extrêmement simple, par exemple:
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);
oui, c'est du code mort juste pour illustrer comment créer un bloc de code complexe (dans {}) afin de faire quelque chose de si spécifique qui ne devrait pas nous gêner pour la création d'une méthode, AKA inline!
Java9 dispose d'un compilateur "Ahead of time" qui effectue plusieurs optimisations au moment de la compilation, plutôt que de les exécuter, ce qui peut être considéré comme étant en ligne.