Pourquoi Go est-il si lent (par rapport à Java)?


Comme nous avons pu le voir à partir de Le jeu Computer Language Benchmarks en 2010:

  • Go est en moyenne 10 fois plus lent que C
  • Go est 3 fois plus lent queJava !?

Comment cela peut-il être, en gardant à l'esprit que le compilateur Go produit du code natif pour l'exécution?
Compilateurs immatures pour Go? Ou il y a un problème intrinsèque avec la langue Go?

MODIFIER:
La plupart des réponses nient la lenteur intrinsèque de Go languge, affirmant le problème réside dans les compilateurs immatures.
J'ai donc fait mes propres tests pour calculer les nombres de Fibonacci: L'algorithme itératif s'exécute en Go (freebsd,6g) avec la vitesse same comme en C (avec l'option O3). Le récursif terne s'exécute en Go 2 times plus lentement qu'en C (avec l'option-O3; avec-O0 - le même). Mais je n'ai pas vu tomber 10x comme dans le jeu Benchmarks.

Author: Taavi, 2010-04-24

10 answers

Les compilateurs 6g et 8g ne sont pas particulièrement optimisés, donc le code qu'ils produisent n'est pas particulièrement rapide.

Ils sont conçus pour fonctionner rapidement eux-mêmes et produire du code correct (il y a un peu d'optimisation). gccgo utilise les passes d'optimisation existantes de GCC et pourrait fournir une comparaison plus pointue avec C, mais gccgo n'est pas encore complet.

Les chiffres de référence concernent presque entièrement la qualité de la mise en œuvre. Ils n'ont pas une quantité énorme de faire avec les langue en tant que telle, sauf dans la mesure où l'implémentation passe l'exécution à prendre en charge les fonctionnalités de langage dont le benchmark n'a pas vraiment besoin. Dans la plupart des langages compilés, un compilateur suffisamment intelligent pourrait en théorie supprimer ce qui n'est pas nécessaire, mais il arrive un moment où vous truquez la démo, car très peu d'utilisateurs réels du langage écriraient des programmes qui n'utilisaient pas cette fonctionnalité. Déplacer des choses sans les supprimer complètement (par exemple, prédire un appel virtuel destinations en Java compilé JIT) commence à devenir difficile.

FWIW, mon propre test très trivial avec Go quand je le regardais (une boucle d'addition d'entiers, fondamentalement), gccgo a produit du code vers la fin rapide de la plage entre gcc -O0 et gcc -O2 pour C. Go équivalent n'est pas intrinsèquement lent, mais les compilateurs ne font pas tout, encore. Rien d'étonnant pour une langue vieille de 10 minutes.

 103
Author: Steve Jessop, 2010-04-24 12:49:58

Dans la prochaine version de la FAQ Go, quelque chose de similaire à ce qui suit devrait apparaître.

Performance

Pourquoi Go fonctionne-t-il mal sur benchmark X?

L'un des objectifs de conception de Go est de approche de la performance de C pour programmes comparables, mais sur certains repères il fait assez mal, y compris plusieurs en test / banc. Le les plus lents dépendent des bibliothèques pour lesquelles les versions de performances comparables sont pas disponible en Aller. Pour instance, pidigits dépend d'une multi-précision paquet math, et les versions C, contrairement à Go, utilisez GMP (qui est écrit dans l'assembleur optimisé). Référence qui dépendent des expressions régulières (regex-adn, par exemple) sont essentiellement en comparant le stopgap de Go paquet regexp à maturité, fortement bibliothèques d'expressions régulières optimisées comme PCRE.

Les jeux de référence sont remportés par tuning et les versions de la plupart des les critères de référence ont besoin d'attention. Si vous mesurer des programmes C et Go comparables (le complément inverse en est un exemple), vous verrez les deux langues sont beaucoup plus proche dans la performance brute que cela suite indiquerait.

Encore, il y a place à l'amélioration. Les compilateurs sont bons mais pourraient l'être mieux, de nombreuses bibliothèques ont besoin majeur travail de performance, et les ordures collector n'est pas encore assez rapide (même si elle l'était, en prenant soin de ne pas générer des ordures inutiles peut avoir un effet énorme).

Et voici quelques détails supplémentaires sur Le jeu Computer Benchmarks à partir d'un fil de discussion récent de la liste de diffusion.

La collecte des Ordures et de la performance dans gccgo (1)

La collecte des Ordures et de la performance dans gccgo (2)

Il est important de noter que le jeu Computer Benchmarks n'est qu'un jeu. Les personnes ayant de l'expérience dans la mesure du rendement et la planification de la capacité correspondent soigneusement comme avec comme sur les charges de travail réalistes et réelles; ils ne jouent pas à des jeux.

 52
Author: peterSO, 2019-03-04 16:50:07

Ma réponse n'est pas aussi technique que celle de tout le monde, mais je pense que c'est toujours pertinent. J'ai vu les mêmes repères sur le jeu de Repères informatiques quand j'ai décidé de commencer à apprendre Go. Mais je pense honnêtement que tous ces repères synthétiques sont inutiles en termes de décider si Go est assez rapide pour vous.

J'avais écrit un serveur de messages en Python en utilisant Tornado+TornadIO+ZMQ récemment, et pour mon premier projet Go j'ai décidé de réécrire le serveur en Go. Jusqu'à présent, avoir obtenu l' serveur aux mêmes fonctionnalités que la version Python, mes tests me montrent une augmentation de vitesse d'environ 4,7 x dans le programme Go. Attention, je n'ai codé dans Go que depuis peut-être une semaine, et je code en Python depuis plus de 5 ans.

Go ne va que s'accélérer à mesure qu'ils continuent à travailler dessus, et je pense vraiment que cela se résume à la façon dont il fonctionne dans une application du monde réel et non à de minuscules repères de calcul. Pour moi, Go a apparemment abouti à un programme plus efficace que ce que je pourrais produire en Python. C'est mon point de vue sur la réponse à cette question.

 35
Author: jdi, 2012-07-02 05:52:57

Les choses ont changé.

Je pense que la bonne réponse actuelle à votre question est de contester l'idée que go est lent. Au moment de votre demande, votre jugement est justifié, mais aller a depuis gagné beaucoup de terrain en termes de performances. Maintenant, ce n'est toujours pas aussi rapide que C, mais n'est pas près d'être 10 fois plus lent, dans un sens général.

Le langage de l'Ordinateur repères de jeu

Au moment d'écrire ces lignes:

source  secs    KB      gz      cpu     cpu load

reverse-complement
1.167x
Go      0.49    88,320  1278    0.84    30% 28% 98% 34%
C gcc   0.42    145,900 812     0.57    0% 26% 20% 100%

pidigits
1.21x
Go      2.10    8,084   603 2.10    0% 100% 1% 1%
C gcc   1.73    1,992   448 1.73    1% 100% 1% 0%

fasta
1.45x
Go      1.97    3,456   1344    5.76    76% 71% 74% 73%
C gcc   1.36    2,800   1993    5.26    96% 97% 100% 97%

regex-dna
1.64x
Go      3.89    369,380 1229    8.29    43% 53% 61% 82%
C gcc   2.43    339,000 2579    5.68    46% 70% 51% 72%

fannkuch-redux
1.72x
Go      15.59   952 900 62.08   100% 100% 100% 100%
C gcc   9.07    1,576   910 35.43   100% 99% 98% 94%

spectral-norm
2x
Go      3.96    2,412   548 15.73   99% 99% 100% 99%
C gcc   1.98    1,776   1139    7.87    99% 99% 100% 99%

n-body
2.27x
Go      21.73   952 1310    21.73   0% 100% 1% 2%
C gcc   9.56    1,000   1490    9.56    1% 100% 1% 1%

k-nucleotide
2.40x
Go      15.48   149,276 1582    54.68   88% 97% 90% 79%
C gcc   6.46    130,076 1500    17.06   51% 37% 89% 88%

mandelbrot
3.19x
Go      5.68    30,756  894 22.56   100% 100% 99% 99%
C gcc   1.78    29,792  911 7.03    100% 99% 99% 98%

Cependant, il souffre brutalement sur le benchmark de l'arbre binaire:

binary-trees
12.16x
Go      39.88   361,208 688 152.12  96% 95% 96% 96%
C gcc   3.28    156,780 906 10.12   91% 77% 59% 83%
 6
Author: tiffon, 2018-11-13 05:20:38

Malgré l'efficacité pas si bonne de Go sur l'utilisation des cycles CPU, le modèle de concurrence Go est beaucoup plus rapide que le modèle de thread en Java, par exemple, et peut être comparable au modèle de thread C++.

Notez que dans le thread-anneau de référence, Allez a 16x plus rapide que Java. Dans le même scénario, Go CSP était presque comparable à C++, mais en utilisant 4x moins de mémoire.

La grande puissance du langage Go est son modèle de concurrence, la Communication de Processus séquentiels, CSP, spécifié par Tony Hoare dans les années 70, étant simple à mettre en œuvre et adapté aux besoins hautement simultanés.

 5
Author: DLopes, 2018-01-24 23:53:59

Il y a deux raisons fondamentales pour lesquelles Java est plus rapide que Go et C++, et peut être plus rapide que C dans de nombreux cas:

1) Le compilateur JIT. Il peut en ligne des appels de fonction virtuelle à travers plusieurs niveaux, même avec des classes OO, en fonction du profil d'exécution. Cela n'est pas possible dans un langage compilé statiquement (bien que la nouvelle re-compilation basée sur le profil enregistré puisse aider). Ceci est très important pour la plupart des benchmarks qui impliquent des algorithmes répétitifs.

2) Le GC. GC l'allocation de mémoire basée est presque gratuite, par rapport à malloc. Et la pénalité "gratuite" peut être amortie sur l'ensemble de l'exécution - souvent ignorée car le programme se termine avant que toutes les ordures aient besoin d'être collectées.

Il y en a des centaines (des milliers?) de développeurs extrêmement talentueux rendant le GC/JVM efficace. Penser que vous pouvez "coder mieux que tous" est une folie. C'est un problème d'ego humain en son cœur - les humains ont du mal à accepter cela avec une formation appropriée par des talents humains, l'ordinateur va mieux fonctionner que les humains qui l'ont programmé.

Btw, C++ peut être aussi rapide que C si vous n'utilisez pas et des fonctionnalités OO, mais alors vous êtes assez proche de simplement programmer en C pour commencer.

Plus important encore, les "différences de vitesse" dans ces tests sont généralement dénuées de sens. Les coûts d'E / S sont des ordres de grandeur supérieurs aux différences de performances, et donc les conceptions appropriées qui minimisent les coûts d'E / S gagnent toujours - même dans un langage interprété. Très peu de systèmes sont liés au processeur.

En guise de note finale, les gens se réfèrent au "jeu computer language benchmarks" comme une "mesure scientifique". Les tests sont complètement défectueux, par exemple, si vous affichez les tests Java pour nbody. Lorsque j'exécute les tests sur le même système d'exploitation/matériel, j'obtiens environ 7,6 secondes pour Java et 4,7 secondes pour C - ce qui est raisonnable - pas la lenteur 4x des rapports de tests. C'est un appât à clics, de fausses nouvelles, conçu pour générer du trafic sur le site.

Comme une note finale et finale... J'ai couru le tests en utilisant Go, et c'était 7.9 secondes. Le fait que, lorsque vous cliquez sur l'Aller, il la compare à Java, et lorsque vous cliquez sur Java, il la compare à C, devrait être un drapeau rouge pour toute ingénieur.

Pour une comparaison réelle de Java, Go et C++, voir https://www.biorxiv.org/content/10.1101/558056v1 spoiler alert, Java sort en tête dans les performances brutes, avec Go qui sort en tête avec une utilisation combinée de la mémoire et du temps de mur.

 2
Author: robert engels, 2019-03-06 13:23:20

Je pense qu'un fait souvent négligé est que la compilation JIT peut être > compilation statique en particulier pour les fonctions ou méthodes liées tardivement (runtime). Le JIT hotspot décide au moment de L'exécution des méthodes à intégrer, il peut même ajuster la disposition des données à la taille/architecture du cache du PROCESSEUR sur lequel il s'exécute actuellement. C / C++ en général peut compenser (et globalement fonctionnera toujours mieux) en ayant un accès direct au matériel. Pour aller les choses peuvent sembler différentes car son plus haut niveau par rapport à C, mais il manque actuellement un système/compilateur d'optimisation d'exécution. Mon instinct me dit, Gopourrait être plus rapide que Java car Go n'impose pas autant de chasse au pointeur et encourage une meilleure localisation de la structure de données + nécessite moins d'allocation.

 1
Author: R.Moeller, 2016-08-02 18:31:44

En fait, Go est non seulement élégant et efficace au moment de la conception, mais aussi super performant au moment de l'exécution. La clé est d'utiliser le bon système d'exploitation c'est à dire LINUX. Résultat de profilage de performance sous Windows et Mac OS sont, faute d'un meilleur mot, un ou deux ordres de grandeur inférieure.

 1
Author: Dan Marinescu, 2019-05-16 20:40:51

Sous linux, le runtime go est super rapide, parfaitement comparable à c/c++. le runtime go sous Windows et unix ne sont pas dans la même ligue

La comparaison avec java n'est pas si importante, go est à la fois pour le développement du système et des applications (car java ressemble plus à blue collar pour le développement d'applications uniquement). n'entrera pas dans les détails, mais quand des choses comme kubernetes sont écrites en go, vous vous rendez compte que ce n'est pas un jouet convivial pour les consultants d'entreprise

Je ne me souviens pas de Google mentionner même une fois le compromis auquel vous faites référence. go est bien conçu, simple, élégant et efficace pour la conception de programmes de niveau système et application, a des pointeurs, une allocation et une désallocation de mémoire efficaces, évite les complications résultant de l'héritage de mise en œuvre oh si facile à manquer, vous donnant des co-routines et d'autres moyens modernes d'écrire des applications hautes performances dans le temps et encore une fois, go est super rapide sous linux, ce qui est exactement ce pour quoi il a été conçu (très heureux que ce soit le cas)

 0
Author: Dan Marinescu, 2019-05-17 19:53:35

Java et C sont plus explicites avec leurs définitions de données et de méthode (fonction). C est typé statiquement, et Java l'est moins avec son modèle d'héritage. Cela signifie que la façon dont les données seront traitées est à peu près définie lors de la compilation.

Go est plus implicite avec ses définitions de données et de fonctions. Les fonctions intégrées sont de nature plus générale, et l'absence d'une hiérarchie de types (comme Java ou C++) donne à Go un inconvénient de vitesse.

Gardez à l'esprit que Le but de Google pour le langage Go est d'avoir un compromis acceptable entre la vitesse d'exécution et la vitesse de codage. Je pense qu'ils frappent un bon sweet spot sur leur première tentative, et les choses ne feront que s'améliorer à mesure que plus de travail sera fait.

Si vous comparez Go avec des langages typés plus dynamiquement dont le principal avantage est la vitesse de codage, vous verrez l'avantage de la vitesse d'exécution de Go. Aller est 8 fois plus rapide que perl, et 6 fois plus rapide que Ruby 1.9 et Python 3 sur ces repères vous utiliser.

Quoi qu'il en soit, la meilleure question à poser est d'aller un bon compromis dans la facilité de programmation par rapport à la vitesse d'exécution? Ma réponse étant oui et cela devrait s'améliorer.

 -4
Author: Bill C, 2012-08-08 13:59:29