Developpez.com

Le Club des Développeurs et IT Pro

Le langage Go se mesure à C++, Java et Scala

Une nouvelle étude comparative des performances, menée par un ingénieur de Google

Le 2011-06-06 12:47:46, par Idelways, Expert éminent sénior
L'ingénieur de Google Robert Hundt vient de publier un rapport comparatif entre Java, Scala, C++ et Go, le langage de programmation maison de Google.
Ce rapport se base sur l'analyse de différents facteurs suite à l'implémentation compacte du même algorithme dans les quatre langages.

Sans surprise, le langage C++ est le plus économe en mémoire vive et celui qui offre la Runtime la plus rapide.
Le résultat de ce benchmark dévoile en revanche que c'est le langage qui nécessite le plus « d'effort d'optimisation », des manipulations parmi lesquelles certaines sont « à un niveau de sophistication hors de la portée du développeur moyen », affirme Robert Hundt.

La mise en oeuvre du code de l'implémentation Java de l'algorithme a été la plus facile d'après le rapport. L'analyse des performances du langage est en revanche la plus complexe, notamment autour des effets du ramasse-miette (Garbage Collector), très difficile à optimiser.

Le langage Scala, qui tourne sur la JVM, et compile tout comme Java en byte-code, partage la même complexité d'analyse et d'optimisation des performances, mais sa notation concise et les puissantes fonctionnalités du langage offrent la meilleure optimisation de la complexité du code.

Quant à Go, Robert Hundt estime qu'il offre des fonctionnalités de langage intéressantes qui rendent possible l'écriture d'expressions concises et standardisées.
Le rapport rappelle que les compilateurs pour ce langage « restent immatures, ce qui se traduit à la fois sur les performances et la taille de l'exécutable »

Sur ce dernier point, les résultats de l'implémentation sont à la traine pour Go qui produit un exécutable de 1.2 Mo contre 13 Ko pour Java et 41 Ko pour C++.
C++ et Go compilent en code-machine, contrairement à Java et Scala. À ce propos, Go compile nettement plus vite que ses trois rivaux.

Le langage Go a été conçu depuis sa création il y a un an et demi comme un langage de programmation concurrentielle tout en conservant les performances d'un langage de bas niveau comme C++ et étant proche en apparence des langages dynamiques type Python.

Cette étude comparative de Google s'est déroulée en deux phases afin d'offrir l’équivalence la plus objective qui soit.
La première phase n'a utilisé que les fonctionnalités idiomatiques des langages (classes, boucles, schéma d'allocation de la mémoire...), sans utiliser des outils spécifiques destinés à maximiser les performances.

Après la publication des résultats de cette phase, divers ingénieurs de Google se sont attelés à optimiser par tous les moyens disponibles l'implémentation de chaque langage.

La comparaison des résultats des deux phases est d'après l'étude « révélatrice de la difficulté typique d'optimisation dans les langages respectifs ».

Le rapport est consultable via ce lien (PDF, 330 Ko, 10 pages)

Et vous ?

Que pensez-vous des résultats de cette étude ?
Et du langage Go et ses perspectives d'avenir ?
  Discussion forum
29 commentaires
  • TropMDR
    Membre éprouvé
    Envoyé par gorgonite
    avoir un code C compact et performant demande parfois des sacrifices en terme de lisibilité... mais une doc technique est alors indispensable (ou alors des macros bien pensées pour redonner un peu de lisibilité justement)

    des goto partout sur des architectures sans prédiction de cache exotiques, ça peut parfois être intéressant (je me souviens d'un interprète de bytecode Java version threaded-code )
    On parle d'un compilo là. La préoccupation première, c'est qu'il produise un code
    1) correct (dans le sens de "qui fait la même chose que ce qu'a écrit le programmeur)
    2) efficace
    Le fait que le compilo lui même aille vite, c'est assez secondaire. Donc je ne vois vraiment pas l'intéret d'un code moisi juste pour que "ça aille vite".

    Envoyé par gorgonite
    c'est un peu l'idée que je partage (avec un peu plus de diplomatie )
    Ouais mais toi tu es modo, t'as une obligation morale !

    Envoyé par kimelto
    Il y a bien une niche pour Go: les gens comme moi qui n'aime pas le C++ et Java. Jusqu'a present je pouvais compter que sur le C et Python.
    Euh, il n'y a vraiment que 4 langages de programmation de disponible ???

    Envoyé par kimelto
    Alors apres c'est sur que si vous adorez Java vous allez pas aimer Go. Go est en quelque sorte un anti-Java. Les developpeurs de Go aiment dire que Go est oriente Object, Java est oriente Type.
    A part la verbosité, j'aimerai bien savoir de quoi ils parlent
  • Ryu2000
    Membre extrêmement actif
    Effectivement je vois mal le C ou le C++ disparaître un jour.
    Mais bon ça finira probablement par arriver, même avec les mises à jour de ces langages.

    Par contre il ne faut pas ne pas essayer de créer de nouveaux langages.
    Si l'équipe qui à créer le Java s'était dit "il y a déjà le C un nouveau langage n'a pas sa place" on aurait loupé quelque chose.

    Peut être que dans 37 ans Go ce sera la langage le plus performant, léger, optimiser, portable.
  • TropMDR
    Membre éprouvé
    Envoyé par gorgonite
    Il est probable que tous ces défauts seront vite corrigés, d'autant plus que le fait que Go ne soit pas si innovant implique que de nombreux back-ends de compilation existants et performants pourront être adaptés... la seule question étant : pourquoi ne pas l'avoir déjà fait ? la version actuelle de Go ne serait-elle qu'un PoC ?
    J'avoue m'être posé la même question il y a quelques mois quand je m'étais penché sur ce langage. Le but est donc théoriquement d'écrire facilement du code parallèle (multi-coeur ou réparti). Et dans le domaine, comparé à du Scala ou du JoCaml, c'est le niveau zéro de l'idée qu'aurait eu un stagiaire à la pose déjeuner qu'il aurait griffoné sur une serviette en papier.

    Ensuite c'est un compilo théoriquement "from scratch", et ils ont écrit ça... en C. Dans la catégorie "j'aime me faire mal, parce que c'est ça qui est bon", ça se pose là quand même. J'ai d'ailleurs tenté de lire le code de l'allocateur de registre, c'est bourré de goto. Un vrai !@# de bonheur.

    Bref, c'est un langage sans intéret, qui "compile vite" mais produit un code merdique, et qui en plus semble avoir fait tous les choix possible et imaginable pour avoir le processus de développement le plus lent possible. Ca n'ira nul part.
  • TropMDR
    Membre éprouvé
    Envoyé par Tommy31
    Comment "duck typing" et "statiquement et strictement typé" peuvent cohabiter ensemble ?

    Je suis pas un pro d'ocaml, loin de là, mais je pensais que l'inférence de type rendait justement le duck typing impossible.

    Tu as des exemples ? Ca m'intéresse.
    Alors, disons qu'un canard, c'est un objet qui sait faire coincoin. Donc je peux utiliser un canard

    Code :
    1
    2
    3
    let utilise_canard c =
      print_string "J'utilise un canard. ";
      c#fait_coin_coin
    Ensuite tu peux définir un vrai canard

    Code :
    1
    2
    3
    4
    5
    class canard =
      object
        method fait_coin_coin = print_endline "Je suis un canard qui fait coin coin"
        method envoler = print_endline "Je suis un canard et je m'envole"
      end
    Mais tu peux aussi par exemple avoir un vélo qui fait coincoin quand il klaxonne

    Code :
    1
    2
    3
    4
    5
    class velo =
      object
        method fait_coin_coin = print_endline "Je suis un vélo qui fait coincoin quand il klaxonne"
        method pedaler = print_endline "Je suis un vélo et je pédale"
      end
    Et là tu peux utiliser les deux avec utiliser_canard

    Code :
    1
    2
    3
    4
    5
    6
    7
    let () =
      let c = new canard in
      let v = new velo in
      utilise_canard c;
      utilise_canard v;
      v#pedaler;
      c#envoler
    Avec comme output
    Code :
    1
    2
    3
    4
    J'utilise un canard. Je suis un canard qui fait coin coin
    J'utilise un canard. Je suis un vélo qui fait coincoin quand il klaxonne
    Je suis un vélo et je pédale
    Je suis un canard et je m'envole
    Donc voilà, duck typing !

    Pourtant, tout ça est bien statiquement typé. La première fonction a comme type
    Code :
    val utilise_canard : < fait_coin_coin : 'a; .. > -> 'a = <fun>
    ce qui signifie "je suis une fonction qui attend un objet qui a au minimum une méthode 'fait_coin_coin' qui retourne un certain type, et je retourne ce même type"

    D'ailleurs, on peut ajouter une classe avec un type de retour différent
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class canard_compteur =
      object
        val mutable count = 0
        method fait_coin_coin =
          count <- count + 1;
          Printf.printf "Je suis un canard qui a fait coin coin %i fois\n" count;
          count
        method envoler = print_endline "Je suis un canard et je m'envole"
      end
    
    let () =
      let cc = new canard_compteur in
      ignore (cc#fait_coin_coin);
      ignore (utilise_canard cc);
      let i = utilise_canard cc in
      Printf.printf "Le canard a fait coin coin %i fois\n" i
    avec comme sortie
    Code :
    1
    2
    3
    4
    Je suis un canard qui a fait coin coin 1 fois
    J'utilise un canard. Je suis un canard qui a fait coin coin 2 fois
    J'utilise un canard. Je suis un canard qui a fait coin coin 3 fois
    Le canard a fait coin coin 3 fois
    Voilà voilà
  • gangsoleil
    Modérateur
    Bonjour,

    Envoyé par Idelways

    Sans surprise, le langage C++ est le plus économe en mémoire vive et celui qui offre la Runtime la plus rapide.
    Le résultat de ce benchmark dévoile en revanche que c'est le langage qui nécessite le plus « d'effort d'optimisation », des manipulations parmi lesquelles certaines sont « à un niveau de sophistication hors de la portée du développeur moyen », affirme Robert Hundt.
    En meme temps, c'est pour ca que c'est de l'optimisation : ce n'est pas une chose que fait le developpeur moyen, mais une chose que fait un specialiste du domaine.

    Si le but de Go est de faire un langage moyen, permettant a n'importe quel developpeur moyen de faire un programme moyen, ils ont des chances de reussir.
    Par contre, faire optimiser a outrance un developpeur moyen, c'est en faire un expert, et donc on en revient a ce qu'ils reprochent a C++.
  • TropMDR
    Membre éprouvé
    Envoyé par kimelto
    Parce que Go ne gere pas l'heritage, tout simplement.
    Le duck typing est beaucoup plus puissant que ce qu'on peut penser Surtout si on decouple bien les "roles" (e.g. writer, reader, ...) avec les interfaces.
    Si vous voulez du duck typing, de l'héritage, le tout dans un système statiquement et strictement typé, il y a toujours OCaml
  • dolanor
    Membre habitué
    J'aime beaucoup déterrer des topics de prévision après que de l'eau a coulé sous les ponts !
    C'est assez amusant de voir ce qui s'est passé depuis ! Et j'avoue que je partageais votre avis à l'époque aussi. Et pourtant maintenant je suis bien accroc de ce langage.

    Quel est votre avis maintenant sur le sujet ?
  • kimelto
    Futur Membre du Club
    Envoyé par gorgonite
    A la vue de tels résultats, on ne peut que se demander ce qui a réellement poussé Google à sortir son langage Go... il compile vite, mais mal aussi bien en pour optimiser la taille que la vitesse. Il n'est pas si innovant : la plupart de ces concepts sont déjà présents dans d'autres langages de programmation, et il existe pas mal d'études sur leurs optimisations.
    Pour la qualite du code genere, l'implementation officielle produit du code simple sans optimisations avancees. L'idee est d'avoir quelquechose qui marche d'abord. Pour la taille des binaires c'est tout simplement lie au fait que les createurs du language sont contre les "shared object" et que donc chaque binaire inclu la runtime et bibliotheque standard.
    Ces deux problemes sont regles par le second compilateur Go: gccgo, qui est plus lent pour compiler, mais qui produit du code plus optimise et gere les .so

    Envoyé par gorgonite
    la version actuelle de Go ne serait-elle qu'un PoC ?
    Oui et non La version actuelle de Go est plus qu'un PoC mais il a ete decide d'implementer certaines fonctionalite rapidement pour avoir un language fonctionnel et developper l'ecosysteme. On pensera plus particulierement au garbage collector qui est tres simple (et il marche!) mais peut etre reimplemente pour diminuer les pauses liee a un cycle de collection.
  • Qt forever
    Nouveau membre du Club
    ""Sans surprise, le langage C++ est le plus économe en mémoire vive et celui qui offre la Runtime la plus rapide.""

    c'est pour celà , je l'ai choisi
  • xelab
    Membre expérimenté
    Envoyé par kimelto

    Ils parlent surtout du fait que Java encourage heritage, et que donc le programmeur raisonne en pensant aux types.
    L'héritage c'est quand même un principe de la POO! Et puis la généricité permet aussi une certaine souplesse...