BENCHMARK 64 bits C++ vs JAVA
Nous avons déjà réalisé un article sur les performances de C++ et de Java. Les performances se sont grandement améliorées au fil des versions de Java. Java arrivait à compétitionner avec C++ lors de certains tests.Récemment, Sun à sortir la bêta 2 de Java 1.6, nous avons réalisé de nouveau les tests déjà effectués sur cette nouvelle version.
Détail de la machine de test
Cpu | Athlon 64bits 3000+ |
Carte mère | Asus a8n-vm |
Mémoire vive | 896 megs |
Système d'exploitation | Suse Linux 10.1 |
Système de fichier | Reiser |
Information des tests
Les mêmes tests ont été utilisés, aucun fichier source n'a été modifié. Pour de plus amples renseignements sur les sources et détails de chaque fichier, consulté l'autre article.Protocole
Les tests en C++ ont été compilés avec g++ (GCC) 4.1.0 (SuSE Linux). La version de Java est 1.5.0_07 et 1.6.0-beta2. GCJ a aussi été utilisé.En C++ nous avons compilé les fichiers de cette façon :
g++ -O2 -funroll-all-loops -fomit-frame-pointer -ffast-math -march=x86-64 -mfpmath=sse [test].cpp -o [test]
En java, nous avons compilé les fichiers de cette façon:
javac -O [test].java
Les programmes java ont été exécuté en version cliente et serveur.
java [test] java -server [test]
Des tests ont été faits afin de voir les performances des programmes Java en natif à l'aide du compilateur gnu.
gcj -O2 -march=i686 --main=[test] -o [test] [test].java
gcj -O2 -fomit-frame-pointer -ffast-math -march=x86-64 -mfpmath=sse --main=[test] -o [test] [test].java
Paramètre pour chacun des programmes
Les mêmes paramètres que dans le précédent article ont été employé.Tableau des résultats
C++ x86-64 | Java 1.5 | Java 1.5 -server | Java 1.6 | Java 1.6 -server | GCJ optimisé | |
Ackermann | 25320 | 20056 | 20020 | ND | ND | 59705 |
Hash2 | 12080 | 6398 | 5957 | 4995 | 4920 | 11176 |
Matrix | 5720 | 13828 | 13605 | 12169 | 12092 | 9443 |
Objinst | 14560 | 5103 | 4969 | 4972 | 4963 | 28062 |
Strcat | 660 | 1857 | 1680 | 1685 | 1607 | 1983 |
Hash | 11440 | 45638 | 44915 | 34216 | 33982 | 33661 |
Methcall | 7680 | 3273 | 3229 | 3374 | 3188 | 14062 |
random | 3780 | 14640 | 14591 | 14226 | 14225 | 17684 |
fibo | 15950 | 18895 | 17460 | 18076 | 18064 | 26956 |
heapsort | 9300 | 11414 | 11215 | 11756 | 11366 | 10130 |
Nestedloop | 2840 | 17000 | 16936 | 21303 | 21169 | 11805 |
Sieve | 6950 | 14347 | 14340 | 13946 | 13938 | 10418 |
Total | 116280 | 172449 | 168917 | 140718 | 139514 | 235085 |
Analyse des résultats
Puisque deux tests ont échoué sous Java 1.6 le total des tests sous Java 1.6 est faussé. Nous pouvons supposer que leurs résultats pourraient être similaires à ceux obtenus sous Java 1.5.Les résultats de Java 1.6 seraient ainsi globalement inférieurs à ceux de Java 1.5. Le test nestedloop affecte grandement Java 1.6, il semble avoir un problème, sans ce test, nous pouvons remarquer que Java 1.6 a amélioré les performances par rapport à son prédécesseur.
Les résultats sont similaires au premier article, Java s'en sort encore une fois très bien. GCJ continue d'avoir de la difficulté dans ce test.
Java 1.6 prend un avantage sur la version 1.5. Le Code C++ semble poser problème. Il est surement possible d'optimiser cela.
Le C++ se resaisie dans ce test. Il est au minimum deux fois plus vite que les versions Java. Malgré que le processeur soit plus rapide et qu'il y ai plus de mémoire, le C++ en tire beaucoup moins partie que les versions Java.
GCJ obtient des performances déplorables, presque deux fois plus lent que la version C++.Les deux versions de Java obtiennent des performances similaires.
Le code Java emploie des StringBuffer qui sont beaucoup plus rapides que des String. Depuis Java 1.5 des StringBuilder peuvent être employés, elles sont encore plus rapides que les StringBuffer. J'ai modifié le source pour voir le gain apporté par ce nouveau type de donnée et le gain a été de 200.
Nous pouvons remarquer que les performances obtenues par les versions Java sont inférieures à celle obtenue dans le précédent article. La version 64 bits de la JVM serait moins performante que la version 32 bits?
Idem que précèdent les performances sont moins bonnes.
La version C++ est dans une classe à part, elle est 3 fois plus rapide que les versions Java.
Les versions Java se sont rapprochées de la version C++ par rapport à la l'article précédèrent.
L'écart dans l'article précédemment était faible, il augment cette fois-ci.
Les résultats sont décevant pour Java 1.6, la version 1.5 est 24% plus rapide.
Aucune amélioration notable du côté de Java
Emprunte mémoire
Durant l'exécution des tests, le taux de mémoire employée et le taux d'usage du CPU ont été pris. Pour l'ensemble des tests, le CPU était utilisé à 99,9%. Concernant la mémoire, c'est plus complexe étant donné que des librairies sont partagées et ne sont pas prises en compte par les outils d'évaluation. Néanmoins à l'aide de la commande top, j'ai pu remarquer que C++ s'en sortait beaucoup mieux que ses confrères. Les versions de Java font majoritairement 50% mieux que la version de GCJ.Facteur à prendre en considération
Performance
Les performances sont importantes, afin de bien optimiser un logiciel, l'utilisation de profiler est indispensable. Ce type d'outils permet de savoir où sont les goulots d'étranglement de l'application. Il est plus sage d'investir du temps dans une portion qui exécuté à 45% du temps par le logiciel qu'une autre qui n'est exécutée que 2% du temps.Java permet de faire appel à du C++ à l'aide de JNI. À partir d'un programme Java, il est ainsi possible de faire appel à des fonctions en C++. Cette approche peut s'avérer intéressante lorsqu'une portion critique d'un programme Java n'atteint pas les performances souhaitées.
L'expérience du programmeur n'est pas un facteur à négliger. Même s'il est possible de faire du code très rapide en C++, encore faut'-il être en mesure d'y parvenir sans même la stabilité du système en péril.