web-dev-qa-db-fra.com

Conseils d'optimisation Java obsolètes

Il existe de nombreux conseils de performance rendus obsolètes par le compilateur Java et en particulier Optimisation guidée par le profil . Par exemple, ces optimisations fournies par la plate-forme peuvent réduire considérablement (selon les sources) le coût des appels de fonctions virtuelles. VM est également capable d'insérer des méthodes, de dérouler des boucles, etc.

Quelles sont les autres techniques d'optimisation des performances que vous avez trouvées qui sont encore appliquées mais qui sont en fait rendues obsolètes par les mécanismes d'optimisation que l'on trouve dans les JVM plus modernes?

42
Dan

Le dernier modificateur des méthodes et des paramètres de méthode n’aide en rien la performance.

En outre, le Java HotSpot Wiki donne un bon aperçu des optimisations utilisées par HotSpot et de la manière de les utiliser efficacement dans le code Java.

23
Eugene Kuleshov

Personnes remplaçant String a = "this" + var1 + " is " + var2; par plusieurs appels à StringBuilder ou StringBuffer. En fait, il utilise déjà StringBuilder en coulisse.

20
Paul Tomblin

Il est nécessaire de définir des compromis temps/mémoire avant de commencer l'optimisation des performances. Voici comment je le fais pour mon application critique en termes de mémoire et de temps (en répétant certaines des réponses ci-dessus, pour être complet):

  1. Règle n ° 1 Ne jamais l'optimisation des performances sur la première étape de développement. Ne le faites jamais si vous n'en avez pas vraiment besoin. Si décidé de le faire, alors:
  2. utilisez le profileur pour rechercher les goulots d'étranglement, passez en revue le code source pour trouver les raisons des goulots d'étranglement;
  3. choisissez la structure de données appropriée qui correspond le mieux aux compromis temps/mémoire définis;
  4. choisir les algorithmes appropriés (par exemple, itération vs récursivité, etc.);
  5. évitez d'utiliser des objets synchronisés de la bibliothèque Java, si vous n'en avez pas vraiment besoin;
  6. éviter explicitement/implicitement la création de nouveaux objets;
  7. redéfinissez/réimplémentez les types de données/algorithmes fournis avec Java si et seulement si vous êtes sûr qu'ils ne répondent pas à vos exigences.
  8. Utilisez de petits tests indépendants pour tester les performances des structures algos/données sélectionnées.
16
khachik

En 2001, j'ai créé des applications pour un téléphone J2ME. C'était la taille d'une brique. Et très près de la puissance de calcul d'une brique.

Pour que les applications Java fonctionnent de manière acceptable, il fallait les écrire de manière aussi procédurale que possible. En outre, l’amélioration très importante des performances consistait à intercepter la ArrayIndexOutOfBoundsException afin de sortir des boucles pour tous les éléments d’un vecteur. Pensez à ça!

Même sur Android, il existe des boucles "rapides" à travers tous les éléments d'un tableau et des façons "lentes" d'écrire la même chose, comme mentionné dans les vidéos de Google IO sur dalvik VM internes.

Cependant, en réponse à votre question, je dirais qu'il est très inhabituel de devoir optimiser ce type de choses ces temps-ci, et je m'attendrais également à ce que sur un JIT VM (même le nouveau Android 2.2 VM, qui ajoute JIT), ces optimisations sont sans objet. En 2001, le téléphone utilisait un interpréteur KVM à 33 MHz. Maintenant, il fonctionne dalvik - une VM beaucoup plus rapide que KVM - de 500 MHz à 1500 MHz, avec une architecture beaucoup plus rapide ARM (meilleur processeur permettant même des gains de vitesse d'horloge ) avec L1 etc. et JIT arrive.

Nous ne sommes pas encore dans les domaines où je serais à l'aise avec la manipulation directe de pixels en Java - que ce soit au téléphone ou sur le bureau avec un i7 -, donc il existe toujours du code normal pour lequel Java n'est pas assez rapide. Voici un blog intéressant qui affirme un expert a déclaré que Java représente 80% de la vitesse C++ pour certaines tâches lourdes du processeur; Je suis sceptique, j'écris du code de manipulation d'image et je vois un ordre de grandeur entre Java et les boucles natives pour les pixels. Peut-être que je manque un truc ...? :RÉ

8
Will
  1. N'appelez pas manuellement le ramasse-miettes, cela nuirait aux performances des implémentations JVM modernes.
  2. Entier au lieu de Long ne vous fera pas économiser beaucoup d’espace, mais limitera la plage des nombres.
  3. Évitez les classes Enum générées à la main et utilisez plutôt l’énumération intégrée. Java 1.5 a introduit de véritables Enums, utilisez-les.
4
Michael Shopsin

Lorsque vous utilisez une machine virtuelle x64 avec RAM moins de 32 Go :

La JVM 64 bits utilise 30% à 50% de mémoire supplémentaire par rapport à la JVM 32 bits en raison de la présence de pointeurs d'objet ordinaires plus grands. Vous pouvez fortement réduire ce facteur en utilisant JDK6 +.

De JDK6u6p à JDK6u22, il est facultatif et peut être activé en ajoutant un argument JVM:

-XX:+UseCompressedOops 

À partir de JDK6u23 (JDK7 également), il est activé par défaut. Plus d'infos ici .

2
Waldemar Wosiński
  1. "L'optimisation prématurée est la racine de tout mal" (Donald Knuth)
  2. Il est utile d’optimiser uniquement les goulots d’étranglement.
  3. Vous devriez analyser le code dans chaque situation. Peut-être que vous pouvez remplacer le TreeSet par un HashSet rapide parce que vous n'avez pas besoin de la fonctionnalité de tri ou peut-être que vous pouvez utiliser float au lieu de double (regardez le SDK Android).
  4. Si aucune technique ne vous aide, vous pouvez essayer de réécrire un morceau de code et de l'appeler via JNI , afin que le code natif fonctionne.
1
Vladimir Ivanov

J'ai trouvé des liens ci-dessus obsolètes. Voici un nouveau sur l'optimisation Java: http://www.appperfect.com/support/Java-coding-rules/optimization.html

0
Zon