CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Différence exécution C++, Java (+ Scala)

Caletlog
Caletlog
Niveau 10
30 juin 2014 à 17:48:27

Salut,

Je trifouillais un peu sur du Scala récemment, et j'ai été surpris de la relative lenteur de la bête, malgré ce qu'on en dit. Du coup, j'ai voulu faire des tests, pas du tout significatifs, pour comparer ça à C++ et Java, et les résultats m'ont quelque peu... surpris, ne serait-ce qu'entre C++ et Java.
Voyez par vous-même :

Code en java : http://pastebin.com/9XGJBSmq
Code en C++ : http://pastebin.com/DHvfw9tG
Code en Scala : http://pastebin.com/WiyYrRDP

Donc, un petit test basique, une boucle d'un milliard d'itérations (petite différence, on a une assignation pour le code Java, parce que je connais pas particulièrement le Java et que le compilo me faisait une erreur sans)

Et là, exécution :

$ time java Test

java Test 0,22s user 0,03s system 104% cpu 0,238 total

$ time ./test

./test 9,34s user 0,01s system 99% cpu 9,400 total

$ time scala TestScala

scala TestScala 11,46s user 0,16s system 101% cpu 11,459 total

Comme vous le voyez, le Java bronche pas alors que le cpp et le scala sont bien plus longs.
Du coup, j'ai un peu de mal à comprendre d'où ça vient. De ce que j'ai pu voir, j'ai ~0.2s de chargement de la JVM quand j'exécute Java, et ~0.9s de chargement de cette même JVM+libs Scala quand j'exécute du Scala. Mais, même sans ces délais, la différence est énorme.
C'est sans doute tout bête, mais quelqu'un sait pourquoi on a une telle différence, même déjà juste entre le java et le C++ ? Et, éventuellement, avec le Scala ?

(pour le Scala, on passe à 2,2s d'exécution pour le même code si je passe -optimize au compilo, mais la compilation dure une cinquantaine de secondes au lieu des ~15 habituelles).

Bon, ça reste toujours plus rapide que de l'interprété (le code ruby ( http://pastebin.com/064rF2xu ) mets 3min :hap: ) mais ça m'étonne quand même.
Comment ça se fait que le Java bronche pas, que la boucle fasse 10 ou 1000000000 itérations, par rapport au CPP ? :(

Aldebran
Aldebran
Niveau 10
30 juin 2014 à 18:17:12

Déjà tes différents code ne font pas la même chose, difficile de se baser la-dessus pour comparer les perfs de différents langages.

Ensuite entre Java et C++ il y a des optimisations qui peuvent entrer en compte : par défaut le code Java est fortement optimisé alors qu'il faut généralement le spécifier au compilateur lorsqu'on veut optimiser du C++ (ajout du flag -O2 par exemple avec g++). Ainsi, ça ne m'étonnerait pas que Java n'évalue même pas l'expression z = x * x : la valeur affectée n'est jamais lue et l'opération x * x n'a pas d'effet de bord, l'instruction n'a donc aucun intérêt.

Concernant Scala, je ne sais pas trop. Utiliser des boucles for n'est pas forcément une bonne idée. Je ne sais pas comment va être interprété ton code, mais c'est possible que ça définisse une collection de 1 000 000 000 d'éléments sur laquelle tu itères. Et même si les éléments de cette collection sont générés au fur et à mesure des besoins, peut-être que les éléments générés restent stockés en mémoire (ce qui impose de réallouer régulièrement de l'espace).

Caletlog
Caletlog
Niveau 10
30 juin 2014 à 18:24:48

" Déjà tes différents code ne font pas la même chose, difficile de se baser la-dessus pour comparer les perfs de différents langages. "

:d) Ah ? Mise à part le Java qui fait une assignation, c'est la même chose, non ?

"Ainsi, ça ne m'étonnerait pas que Java n'évalue même pas l'expression z = x * x : la valeur affectée n'est jamais lue et l'opération x * x n'a pas d'effet de bord, l'instruction n'a donc aucun intérêt. "

:d) Ah d'accord, effectivement ça semble logique et ça expliquerait pourquoi le temps ne varie pas pour i de 10 à 1.10e8.

Pour le Scala, c'est plausible, mais c'est vraiment toutes les opérations qui semblent être affreusement longues. Un simple "Hello World!" statique mets 0.9s ; un simple "Hello " + args(0) mets 1.7 secondes, et ce sont pourtant les exemples d'Odersky dans son livre :(

Caletlog
Caletlog
Niveau 10
30 juin 2014 à 18:25:22

(Merci pour ta réponse en tout cas, ça m'éclaircit pas mal de points :) )

LEpigeon-888
LEpigeon-888
Niveau 12
30 juin 2014 à 19:31:37

Tu peux juste faire le test sur ta machine et me dire combien de temps ça met pour le C++ avec g++ avec l'option -O2 s'il te plait ? :(

J'aimerais bien savoir :hap:

LEpigeon-888
LEpigeon-888
Niveau 12
30 juin 2014 à 19:34:01

Voir même -O3 en fait :(

Caletlog
Caletlog
Niveau 10
30 juin 2014 à 19:38:39

Mêmes résultats sans, avec -O2 et avec -O3.

Sinon, étrange. Je viens de tester le scala sur ma machine fixe sous debian Stable, moins puissante que mon laptop (sous debian Testing), et là, Scala est bien plus rapide : 0.2s pour un Hello World, pas de différences avec un Hello World statique ou un print des arguments, et 'seulement' 7 secondes pour le test des itérations, soit presque 2 fois plus rapide :(

J'ai pensé que c'était du à la version d'openjdk et icedTea, mais j'ai les mêmes résultats sur mon laptop en repassant en openjdk-6 et icedTea-1.12 (contrairement à openjdk-7 et icedTea-2.24) :(

godrik
godrik
Niveau 30
30 juin 2014 à 20:32:09

Caletlog, il n'y a aucune raison qu'un code java soit plus rapide qu'un code C++ equivalent. Les seuls exemple que j'ai pus voir etait liee a un programmeur C++ qui ne comprenait pas ce qu'ils faisait (en particulier, comment gerer de la memoire).

Des que tu fais des tests de performance, il faut comparer des choses en utilisant pleinement ses outils, et donc souvent c'est une compilation en -O2 ou -O3 avec declaration de l'architecture qui va bien (dans gcc -march=native ).

Si tu as des questions de perf, n'hesite pas a les poser, c'est un peu mon boulot :) En passant une colle: ecrit le code qui fait le plus d'operation floatante par secondes. Je me contre fout de ce que les operations font ou de la logique derriere ces operation. Met juste le plus d'operation flotante que tu peux par secondes.

Poste les caracteristiques de ton (tes?) processeur(s?) avec tes resultats.

Caletlog
Caletlog
Niveau 10
30 juin 2014 à 21:58:38

godrik > Je veux bien ; c'est ce que je pensais aussi. Mais du coup je comprends pas mes résultats ^^"
On est d'accord, ces deux programmes font bien la même chose, maintenant ?

https://image.noelshack.com/fichiers/2014/27/1404158200-2014-06-30-215533-883x578-scrot.png

Alors pourquoi de tels résultats ? (fenêtre du bas)

Pour ta dernière question, je suis pas sûr de comprendre ce que tu veux montrer en fait... Un truc comme ça, tu veux dire ? http://stackoverflow.com/questions/8389648/how-do-i-achieve-the-theoretical-maximum-of-4-flops-per-cycle

Bunyan
Bunyan
Niveau 17
30 juin 2014 à 22:34:54

@Aldebran : " [...] par défaut le code Java est fortement optimisé [...]"

Non, même plutôt l'inverse en fait. Le compilateur standard (javac) de Java n'optimise strictement rien, ou extrêmement peu. Par contre, la VM, avec le compilateur Just in Time (JIT) fait des optimisations bytecode assez agressives pour les passages les plus utilisés.

Pour être fixé, il suffit de regarder le bytecode Java généré par la compilation. Il y aura toutes les instructions, mêmes les prévisions standard pouvant être évitées statiquement.
Celles-ci seront par contre simplifiées/optimisées au runtime après quelques passages.

Pseudo supprimé
Pseudo supprimé 30 juin 2014 à 22:55:19

hotspot 1.8, g++ 4.9, amd64
g++ -O2: 0m0.963s
g++ -O3: 0m1.220s (utilisation abusive de SSE)
hotspot: 0m1.010s

hotspot génère beaucoup plus d'instructions que g++ (O2)
https://gist.github.com/aanonymous/c9165bbd566dd9569919

LEpigeon-888
LEpigeon-888
Niveau 12
30 juin 2014 à 23:20:09

Rien à voir mais ça m'intrigue, c'est quoi ta police ? :hap:

godrik
godrik
Niveau 30
01 juillet 2014 à 00:27:59

Perso, je vois la meme chose que elite a peu de chose pres.

Caletlog, ce que j'essaye de te dire c'est que si tu t'interesse a la performance, il faut regarder l'execution telle qu'elle se passe dans ton processeur. Et la j'ai l'impression que tu te poses les mauvaises questions.

La question est:
-quelles sont les instructions assembleur qu'il faut emettre?
-pourquoi java emet ces instructions assembleur la?
-pourquoi gcc emet ces instructions assembleur la?
-comment modifier le code pour que le compilateur prenne la bonne decision?

Quand tu va commencer a regarder ces choses, tu pourrais bien trouver des strategie d'execution differente. Par exemple, ce qui est complique dans ton probleme, c'est que tu travailles sur des long. Et que les long c'est la mort. En particulier parceque les vecteur de long n'ont pas l'air de bien se multiplier. Mais si tu note que tes i sont en fait 32 bit, tu dois pouvoir utiliser un truc comme "pmuldq" pour faire ce que tu veux un peu plus vite.

Caletlog
Caletlog
Niveau 10
01 juillet 2014 à 09:44:37

godrik > ah okay, je vois 'de loin' le problème.
Ça m'a l'air franchement intéressant, mais je t'avoue que je suis loin d'avoir le niveau pour comprendre ça, je pense. J'ai que de très vagues notions d'assembleur et d'architecture alors je bloque déjà sur vos posts, avec elite :rouge:

LEpigeon-888 > C'est du Termsyn.

LEpigeon-888
LEpigeon-888
Niveau 12
01 juillet 2014 à 21:54:21

Merci :oui:

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment