J'utilisais Je passe Aujourd'hui, je suis revenu pour effacer cette performance telledo de la liste. J'ai donc couru quelques tests de J'ai écrit un peu à ce sujet, ici: http://biasedbit.com/blog / New-vs-NewInstance / P>
(Désolé pour la promotion de soi ... Je placerais le texte ici, mais cette question se développerait de proportions.) p>
Qu'est-ce que j'aimerais savoir, c'est pourquoi le drapeau J'ai appris ma leçon avec toute la chose des réflexions, il s'agit simplement de curiosité des optimisations que JVM effectue en exécution, en particulier avec le drapeau Edit: J'ai ajouté une phase d'échauffement et les résultats sont maintenant plus stables. Merci pour l'entrée! P> NewInstance () Code> dans une zone critique de performance de mon code.
La signature de la méthode est la suivante: p>
quelque chose.class code> comme argument, je reçois une instance de
quelque chose code>, créé avec
NewInstance () Code>. p>.
nouvel opérateur code> versus
NewInstance () Code>. J'ai été très surpris de la pénalité de performance de
NewInstance () Code>. P>
-SERVER CODE> fournit-il un tel boost de performance lorsque le nombre d'objets créés augmente largement et non pour les valeurs "basses", disent, 100 ou 1000. P>
-Server code>. En outre, si je fais quelque chose de mal dans le test, j'apprécierais vos commentaires! P>
3 Réponses :
Entre autres choses, le profil de collecte des ordures pour l'option sur la lecture plus proche, je vois que votre exemple est un Micro-Benchmark < / a> et les résultats peuvent être contre-intuitifs. Par exemple, sur ma plate-forme, des appels répétés sur -Server code> a de manière significative Superposition de l'espace survivant par défaut. P>
NewInstance () code> sont effectivement optimisés lors des exécutions répétées, rendant
NewInstance () code> apparaissent 12.5 fois plus rapidement que
neuf code>. p>
J'ai couru avec -xx: + printgcDétails et j'ai vu seulement 1 collection - la collection complète I forcée entre les deux tests. Je me suis assuré de fournir suffisamment de mémoire à l'application afin qu'il n'aurait pas besoin de redimensionner ou de collecter (en fait, je m'empêchais également de redimensionner en utilisant les mêmes -xmx que -xms). Dans ces conditions, je pense que GC n'était pas un facteur décisif dans les résultats.
@brunodecarvalho: Oui, je vois ce que tu veux dire, et j'ai élaboré ci-dessus. Vous devrez peut-être réécrire votre référence pour obtenir des résultats significatifs.
Oui, j'avais peur de l'effet de micro-étagère ici. Je n'aijoute que la nouvelle instance à ce réseau d'objet dans l'espoir que le compilateur ne réaliserait pas que c'est une opération inutile et supprimez toute la boucle. Je vais tester cela à nouveau à l'aide du système que j'étais sur le point d'optimiser. Cependant, je trouve un peu étrange que NewInstance () devient plus rapide que neuf. En regardant à travers la source de JDK, semble qu'il y a beaucoup de frais généraux que NewInstance () passe et nouvelle ne le fait pas.
@brunodecarvalho: Je pense qu'un constructeur trivial est optimisé, tandis qu'un constructeur non trivial vient à dominer le temps pour l'un ou l'autre.
J'ai appris ma leçon avec toute la chose des réflexions, il s'agit simplement de curiosité des optimisations que la JVM fonctionne en exécution, en particulier avec le drapeau -Server. En outre, si je fais quelque chose de mal dans le test, j'apprécierais vos commentaires! P> blockQuote>
Répondre d'abord à la deuxième partie, votre code semble faire l'erreur classique pour les micro-repères Java et ne pas "réchauffer" la JVM avant de faire vos mesures. Votre application doit exécuter la méthode qui effectue le test à quelques reprises, ignorant les premières itérations ... au moins jusqu'à ce que les chiffres se stabilisent. La raison en est qu'un JVM doit faire beaucoup de travail pour obtenir une demande démarrée; par exemple. Chargement de cours et (quand ils sont courus quelques fois) JIT Compilation des méthodes où le temps d'application significatif est en cours de dépensement. P>
Je pense que la raison pour laquelle "-Server" fait une différence est que (entre autres), il modifie les règles qui déterminent quand le JIT compile. L'hypothèse est que pour un "serveur", il est préférable de jit plus tôt cela donne une start-up plus lente mais un meilleur débit. (En revanche, un "client" est syntonisé pour différer JIT Compiler afin que l'utilisateur obtienne une interface graphique de travail plus tôt.) P>
J'ai ajouté quelques itérations d'échauffement avant d'avoir couru les tests réels et je vais de mieux, des chiffres plus stables. Avec -Server Drapeau, NewInstance () se stabilise à 2,5 ~ 2,9 fois plus lentement que neuf (à la fois pour des objets 100 et 1 kmk). Sans le maintien, il est toujours aussi élevé que 8 ~ 9 fois plus lentement pendant 100 objets jusqu'à 25 lents pendant 1 kk). Très bon conseil! :)
Un meilleur moyen de réchauffer correctement le JVM, est de le transmettre les arguments de la ligne de commande -XX: + de la commande d'impression qui fera imprimer la compilation et des optimisations de JVM. Assurez-vous ensuite qu'aucune des étapes de compilation ne se produit pendant votre course chronométrée.
@Lordoftheppigs - je suis en désaccord. En général, le meilleur moyen est de faire fonctionner un grand nombre d'itérations (alternatives), enregistrer les temps et jeter les premiers anormaux. Puis moyenne. Cela s'occupe d'autres sources de problèmes et de jitage. Le -xx: + ImprimerCompilation Code> Approche seulement adresses JIT Anomalies.
IMHO La pénalité de performance provient du mécanisme de chargement de la classe. En cas de réflexion, tout le mécanisme de sécurité est utilisé et donc la pénalité de création est plus élevée. En cas de nouvel opérateur, les classes sont déjà chargées dans VM (cochées et préparées par le chargeur de classe par défaut) et l'instanciation réelle est un processus bon marché. Le paramètre -Server fait beaucoup d'optimisations JIT pour le code fréquemment utilisé. Vous voudrez peut-être l'essayer également du paramètre -Batch qui échangera le démarrage de la démarrage, mais le code fonctionnera plus rapidement. p>
Votre explication a du sens, comme je l'ai examiné le code et que l'ensemble du mécanisme de sécurité ajoutait une surcharge générale importante. Cependant, le drapeaubatch ne semble pas être valide.
@brunodecarvalho: Vous avez raison! La syntaxe est -xbatch n'est pas lot comme je l'ai tapé. Pour plus de détails, voir: download.oracle.com/docs/cd/e17476_01/javase/1.4.2/docs/... et Download.Oracle.com/docs/cd/e17409_01/javase/6/docs/technote S / ...
N'a pas semblé faire beaucoup de différence. J'ai supprimé la phase d'échauffement pour voir si cela affecterait les résultats, mais je reçois à peu près les mêmes valeurs avec -xbatch et sans. Néanmoins, c'est un drapeau très intéressant!
Le blog post a déplacé à nouveau .
L'article Biasedbit.com/new-vs-newinstance n'existe pas!