J'ai vu d'autres threads disant que les performances de réflexion Java sont de 10-100 fois plus lentement que lors de l'utilisation d'appels non réflexes.
Mes tests dans 1,6 ont montré que ce n'est pas le cas, mais j'ai trouvé d'autres choses intéressantes que je Besoin de quelqu'un pour m'expliquer. P>
J'ai des objets qui implémentent mon interface. J'ai fait trois choses 1) en utilisant une référence à un objet que j'ai lancé cet objet à l'interface et appelez la méthode via l'interface 2) à l'aide d'une référence à l'objet réel appelez la méthode directement et 3) appelez la méthode par réflexion. J'ai vu que l'appel d'interface n ° 1 a été le plus rapide suivi de près par la réflexion n ° 3, mais j'ai remarqué que l'appel de la méthode directe était le plus lent par une bonne marge. P>
Je ne comprends pas cela, je n'aurais pas attendu L'appel direct doit être le plus rapide, puis l'interface, puis la réflexion serait beaucoup plus lente. p>
bla et complexclass sont dans un package différent de la classe principale et ont à la fois une méthode de dosage (int x) qui Implémente l'interface et imprime simplement l'entier X. P>
Voici mes résultats (Times in MS, Résultats Très similaire avec des essais multiples): Appeler une méthode directement: 107194 Appeler une méthode directement à partir d'un objet Cast à une interface: 89594 Appeler une méthode via la réflexion: 90453 P>
Voici mon code: p>
3 Réponses :
Mettre en place tous les tests dans le même programme est une erreur de microbenchement - il y a un certain échauffement associé à la performance Java. C'est l'échec le plus important. P>
Mettez vos tests dans des programmes distincts. Puis exécutez les tests à plusieurs reprises, vous avez donc une sensation de réchauffement et une signification statistique. P>
Aussi, vous avez une énorme méthode contenant votre boucle interne. Hotspot semble être mieux à traiter avec ceci que cela n'était-il possible, mais cela n'est toujours pas bon. P>
Vous devez trouver cela avec -Server code> appeler une méthode virtuelle (même si chargé par un chargeur de classe différent) dans une boucle serrée est complètement optimisée. Il n'a donc pas beaucoup de sens de dire à quel point un appel rapide est qu'un appel réfléchissant. P>
Que voulez-vous dire qu'il y a une énorme méthode contenant la boucle intérieure? Dites-vous que la méthode de test elle-même est trop grande? Pourquoi c'est un problème? Qu'est-ce que c'est -server?
Et je vois votre point avec le problème que les tests individuels ne sont pas dans leurs propres méthodes. Bien que j'ai un sentiment, je vais voir des résultats similaires. Fera un poste séparé probablement une fois que j'ai obtenu ces résultats.
Vous avez une grande méthode d'essai qui itière autour des boucles des millions de fois. -Server est le commutateur aller plus rapide (mais augmente les temps de démarrage, et n'est pas nécessairement présent, en particulier sur les fenêtres JRE). Les tests doivent être dans leur propre processus. Exécutez le programme frais pour chaque test.
Premièrement, la réflexion a beaucoup plus rapide dans les derniers JDK. Deuxièmement, je m'attends à ce que le compilateur Hot Spot optimise tous ces appels à environ le code. Il peut faire une analyse du temps d'exécution pour réaliser que vous appelez la même fonction encore et encore afin de pouvoir optimiser la réflexion (et l'appel de la fonction virtuelle). Même chose avec l'exemple d'interface. P>
Mon test montre que si Java est capable de fonctionner en ligne, l'invocation directe peut être extrêmement rapide. Dans l'appel direct doublé est 200-300 fois plus rapide que l'appel de réflexion. Testé sur Ubuntu 12.10, JDK 1.6.35, CPU Xeon E5-2620.
Java devient plus intelligent et plus intelligent tous les jours. P>
import java.lang.reflect.Method; public class Main { static class Test { int i=0; public void set(int value){ this.i = value; } } public static void main( String[] args) throws Exception { Test test = new Test(); int max = 10000000; long direct = System.currentTimeMillis(); for( int i=0; i<max; i++){ Integer io = new Integer(i*i); test.set(io); } System.out.println("Direct : " + (System.currentTimeMillis() - direct)); Method method = Test.class.getMethod("set", Integer.TYPE); long reflection = System.currentTimeMillis(); for( int i=0; i<max; i++){ Integer io = new Integer(i*i); method.invoke(test, io ); } System.out.println("Reflection : " + ( System.currentTimeMillis() - reflection)); } }
Pourquoi cw? C'est une question de programmation non subjective valide? Et pourquoi les votes pour fermer ?!
J'ai fait le titre dans une question pour ceux qui ne peuvent pas voir une question à moins que cela ait la marque. Mais, wiki communautaire ??