Java : benchmark de la JRE

August 5, 2008

On voit souvent des débats concernant la vitesse de Java par rapport au C++. Les développeurs Java disent que leur langage est plus rapide (sur certains points c’est vrai, mais il n’y en a pas beaucoup) et les développeurs C++ ont souvent des préjugés (très souvent dûs au passé de Java qui n’est pas des plus glorieux).

J’ai donc décidé de comparer, non pas Java avec C++, mais l’évolution de la JRE depuis la version 1.1 à la future 1.7.

Réalisation des benchmarks

J’ai réalisé ces benchs avec différents algorithmes et chargements agressifs de la JVM :

  1. Copie de tableau de 10Mo par la méthode : System.arrayCopy.
  2. Copie de tableau de 10Mo par boucle.
  3. Suite de Fibonacci.
  4. Fonction d’Ackermann.
  5. Exécution de boucles imbriquées.
  6. Concaténation de String dans un StringBuffer.
  7. Copie de matrice.
  8. Appels intensifs de méthodes.
  9. Instanciations intensives d’objets.
  10. Calculs mathématiques.

Les sources de mes benchs sont disponibles : [sources benchmarks de la JRE][1].

Voici la configuration de la machine ayant servie à exécuter les benchs : Intel Core 2 duo cadencé à 3.00 Ghz, 2Go de mémoire, Windows XP Professional SP2.

Tous les résultats sont en millisecondes, sauf pour la taille de la JRE qui elle est en kilooctets.

Taille de la JRE

La JRE n’a cessé de grossir au fur et à mesure des versions avec sans cesse de très nombreuses améliorations de l’API (le point fort de Java).

JRE-Size

Copie de tableau : System.arrayCopy

Dans ce bench je crée un tableau (la création du tableau n’est pas inclue dans les résultats) de 10Mo et je recopie ce même tableau dans un autre tableau grâce à la méthode System.arrayCopy.

JRE-ArrayCopy

Copie de tableau : boucle

Ce bench est très similaire au précédent sauf que le tableau est copié byte à byte par une boucle (ce qui est déjà beaucoup plus long).

JRE-RoughArrayCopy

Suite de Fibonacci

La suite de Fibonacci est un algorithme récursif qui est souvent utilisé pour effectuer des benchmarks. Cela dit les résultats sont très parlant quand à l’évolution de la récursivité dans la JVM.

JRE-Fibonacci

Fonction d’Ackermann

La fonction d’Ackermann est aussi un algorithme récursif un peu plus agressif que la suite de Fibonacci.

JRE-Ackermann

Boucles imbriquées

Ce test va tout simplement exécuter plusieurs boucles imbriquées et utiliser la valeur des index des boucles.

JRE-Loops

Comme souvent les premières versions de la JRE (version 1.1 et 1.2) qui étaient très légères sont beaucoup plus performantes que les versions récentes, sauf pour la 1.6 et la future 1.7 dont les performances ont été grandement améliorées.

Concaténation StringBuffer

Dans ce bench je crée un StringBuffer *auquel je concaténe la chaîne “azertyuiopqsdfghjklmwxcvbn0123456789*” un million de fois.

JRE-StringBuffer

Dans ce bench on voit que la gestion des String a été très largement améliorée depuis la première version de la JRE (presque deux fois plus rapide).

Copie de matrice

La multiplication de matrices permet de vérifier la vitesse de calcul de la JVM. Je teste ici 10000 multiplications de deux matrices 30×30.

JRE-Matrix

Appels de méthodes

Ce bench instancie deux objets très simples (objets à deux états) et appel leurs méthodes 100 millions de fois chacuns. L’instanciation des objets n’est pas inclue dans les résultats.

JRE-MethodCall

Instanciation d’objets

Ce test met en évidence que Java est un langage Objet. Depuis la version 1.1 jusqu’à la version actuelle le temps d’instanciation de 100 millions d’objets a été divisé par 16 en passant de 25 313ms a 1547ms.

JRE-Instanciation

Calculs mathématiques

Ce test effectue 10 millions d’opérations mathématiques (modulo, division, …) en utilisant le résultat précédent comme paramètre de la fonction.

JRE-Math

Conclusion

Si on agrège tous ces résultats pour obtenir une approximation de la vitesse d’exécution de la JRE (attention ce résultat est à relativiser, je n’ai pas effectué tous les benchmarks possibles), on observe que ce qui joue le plus grand rôle est l’instanciation des objets, or Java se veut être LE langage objet du moment.

JRE-Conclusion

Si vous avez des benchs a me soumettre je les ajouterais à ce billet.

[1]: http://www.mkhelif.fr/uploads/2008/08/benchmark.jar "Benchmark"