Performance C++ vs. Java / C#
ma compréhension est que C/c++ produit du code natif pour fonctionner sur une architecture de machine particulière. À l'inverse, des langages comme Java et C# s'exécutent sur une machine virtuelle qui fait abstraction de l'architecture native. Logiquement, il semble impossible pour Java ou C# de correspondre à la vitesse de C++ à cause de cette étape intermédiaire, mais on m'a dit que les derniers compilateurs ("hot spot") peuvent atteindre cette vitesse ou même la dépasser.
C'est peut-être plus question de compilateur qu'une question de langue, mais est-ce que quelqu'un peut expliquer en anglais simple comment il est possible pour l'un de ces langages de machine virtuels pour exécuter mieux qu'une langue native?
30 réponses
en général, c# et Java peuvent être aussi rapides ou plus rapides parce que le compilateur JIT-un compilateur qui compile votre IL la première fois qu'il est exécuté-peut faire des optimisations qu'un programme compilé C++ ne peut pas parce qu'il peut interroger la machine. Il peut déterminer si la machine est Intel ou AMD; Pentium 4, Core Solo, ou Core Duo; ou si elle supporte SSE4, etc.
un programme C++ doit être compilé à l'avance généralement avec des optimisations mélangées de sorte qu'il fonctionne correctement toutes les machines, mais n'est pas optimisé autant qu'elle pourrait l'être pour une seule configuration (c'est à dire processeur jeu d'instructions, d'autres matériels).
en outre, certaines fonctionnalités de langage permettent au compilateur en C# et en Java de faire des hypothèses sur votre code qui lui permettent d'optimiser certaines parties loin qui ne sont tout simplement pas sûres pour le compilateur C/C++ à faire. Quand vous avez accès à des pointeurs, il y a beaucoup d'optimisations qui ne sont tout simplement pas sûres.
aussi Java et C# peut faire des attributions de tas plus efficacement que C++ parce que la couche d'abstraction entre le collecteur d'ordures et votre code lui permet de faire toute sa compression de tas à la fois (une opération assez coûteuse).
maintenant je ne peux pas parler pour Java sur ce prochain point, mais je sais que C# par exemple supprimera les appels de méthodes et de méthodes quand il sait que le corps de la méthode est vide. Et il utilisera ce genre de logique tout au long de votre code.
So comme vous pouvez le voir, il y a beaucoup de raisons pour lesquelles certaines implémentations C# ou Java seront plus rapides.
maintenant tout cela dit, des optimisations spécifiques peuvent être faites en C++ qui vont détruire tout ce que vous pourriez faire avec C#, surtout dans le domaine graphique et chaque fois que vous êtes proche du matériel. Les pointeurs font des merveilles ici.
alors, selon ce que vous écrivez, j'irais avec l'un ou l'autre. Mais si vous écrivez quelque chose qui n'est pas matériel dépendant (pilote, jeu vidéo, etc), Je ne m'inquiéterais pas de la performance de C# (encore une fois je ne peux pas parler de Java). Il va faire tout aussi bien.
Un la Java côté, @Swati , souligne un bon article:
JIT vs. Static Compiler
comme déjà dit dans les billets précédents, JIT peut compiler IL/bytecode en code natif à l'exécution. Le coût en a été mentionné, mais pas à sa conclusion:
JIT a un gros problème, c'est qu'il ne peut pas tout compiler: la compilation JIT prend du temps, donc le JIT ne compilera que quelques parties du code, alors qu'un compilateur statique produira un binaire natif complet: pour une sorte de programmes, le binaire le compilateur sera tout simplement plus performant que le JIT.
bien sûr, C# (ou Java, ou VB) est généralement plus rapide à produire une solution viable et robuste que C++ (ne serait-ce que parce que C++ a une sémantique complexe, et la bibliothèque standard C++, bien qu'intéressante et puissante, est assez pauvre par rapport à la portée complète de la bibliothèque standard de .NET ou Java), donc habituellement, la différence entre C++ et .NET ou Java JIT ne sera pas visible pour la plupart des utilisateurs, et pour les binaires qui sont critique, bien, vous pouvez toujours appeler le traitement C++ à partir de C# ou Java (même si ce genre d'appels natifs peut être très coûteux en soi)...
c++ metaprogramming
notez qu'habituellement, vous comparez le code d'exécution C++ avec son équivalent en C# ou Java. Mais C++ a une fonctionnalité qui peut surpasser Java / C# hors de la boîte, c'est-à-dire le métaprogrammage de modèle: le traitement de code sera fait au moment de la compilation (donc, augmenter considérablement la compilation temps), aboutissant à une durée d'exécution nulle (ou presque nulle).
j'ai encore vu un effet de la vie réelle sur ceci (je n'ai joué qu'avec des concepts, mais à ce moment-là, la différence était des secondes d'exécution pour JIT, et zéro pour C++), mais cela vaut la peine de mentionner, à côté du fait que le métaprogramme de modèle n'est pas anodin...
Modifier 2011-06-10: En C++, jouer avec les types se fait au moment de la compilation, ce qui signifie produire du code générique qui appelle du code non-générique (par exemple un analyseur générique de chaîne à type T, appeler L'API de bibliothèque standard pour les types qu'il reconnaît, et rendre l'analyseur facilement extensible par son utilisateur) est très facile et très efficace, alors que L'équivalent en Java ou C# est au mieux douloureux à écrire, et sera toujours plus lent et résolu à l'exécution même lorsque les types sont connus au moment de la compilation, ce qui signifie Votre seul espoir est pour le JIT pour mettre en ligne l'ensemble.
...
Modifier 2011-09-20: L'équipe derrière Blitz++ ( page d'Accueil , Wikipedia ) y est allé de cette façon, et, apparemment, leur objectif est d'atteindre FORTRAN sur le rendement du calcul scientifique en mouvement autant que possible à partir d'exécution de la compilation temps, par C++ modèle de la métaprogrammation. Donc, le " j'ai encore voir un effet de la vie réelle sur ce "partie I a écrit ci-dessus apparemment ne existent dans la vie réelle.
Natif C++ Utilisation De La Mémoire
C++ a un usage de mémoire différent de Java / C#, et donc, a des avantages/défauts différents.
peu importe l'optimisation JIT, rien ne va plus vite que direct accès pointeur à la mémoire (ignorons pour un moment les caches du processeur,etc.). Ainsi, si vous avez des données contiguës en mémoire, accédez-les par des pointeurs C++ (c.-à-d. des pointeurs C)... Donnons à César son dû) va des fois plus vite Qu'en Java / C#. Et C++ a RAII, ce qui rend beaucoup de traitement beaucoup plus facile qu'en C# ou même en Java. C++ n'a pas besoin de using
pour définir l'existence de ses objets. Et C++ n'a pas de clause finally
. Ce n'est pas une erreur.
:- )
et malgré les structures c# primitives, les objets C++" sur la pile " ne coûteront rien lors de l'allocation et de la destruction, et n'auront pas besoin de GC pour travailler dans un thread indépendant pour faire le nettoyage.
en ce qui concerne la fragmentation de la mémoire, les allocateurs de mémoire en 2008 ne sont pas les anciens allocateurs de mémoire de 1980 qui sont généralement comparés à une allocation GC: C++ ne peut pas être déplacé en mémoire, vrai, mais alors, comme sur un système de fichiers Linux: qui a besoin de disque dur défragmenter quand la fragmentation ne se produit pas? Utiliser le bon allocateur pour la bonne tâche devrait faire partie de la boîte à outils du développeur C++. Maintenant, écrire des allocateurs n'est pas facile, et puis, la plupart d'entre nous ont de meilleures choses à faire, et pour la plupart d'utilisation, RAII ou GC est plus assez bon.
Modifier 2011-10-04: Pour des exemples efficace allocateurs: Sur les plates-formes Windows, depuis Vista, le Faible Le tas de Fragmentation est activé par défaut. Pour les versions précédentes, la LFH peut être activée en appelant la fonction WinAPI informations D'empilage ). Sur d'autres eso, des allocateurs alternatifs sont fournis (voir https://secure.wikimedia.org/wikipedia/en/wiki/Malloc pour une liste)
maintenant, le modèle de mémoire devient un peu plus compliqué avec la montée des technologie multicore et multithreading. Dans ce domaine, je suppose que .NET a l'avantage, et Java, on m'a dit, a tenu le haut du terrain. C'est facile pour un hacker "sur le métal nu" de louer son code "près de la machine". Mais maintenant, il est plus difficile de produire un meilleur assemblage à la main que de laisser le compilateur faire son travail. Pour C++, le compilateur est généralement devenu meilleur que le hacker depuis une décennie. Pour C# et Java, c'est encore plus facile.
toujours, la nouvelle norme C++0x imposera un modèle de mémoire simple aux compilateurs C++, qui normalisera (et donc simplifiera) le code multiprocesseur/parallèle/filetage efficace en C++, et rendra les optimisations plus faciles et plus sûres pour les compilateurs. Mais nous verrons dans quelques années si ses promesses sont tenues.
C++ / CLI vs. C# / VB.NET 151980920"
Note: dans cette section, je parle de C++/CLI, c'est-à-dire le C++ hébergé par .NET, pas le C++natif.
la semaine dernière, j'ai suivi une formation sur l'optimisation.net, et j'ai découvert que le compilateur statique est de toute façon très important. Aussi important que JIT.
le même code compilé en C++ / CLI (ou son ancêtre, géré en C++) pourrait être plus rapide que le même code produit en C# (ou VB.NET, dont le compilateur produit le même IL que C#).
parce que le compilateur statique C++ était beaucoup mieux pour produire du code déjà optimisé que De C#.
par exemple, la fonction inlining in .net est limitée aux fonctions dont le bytecode est inférieur ou égal à 32 octets de longueur. Ainsi, un code en C# produira un accessor de 40 octets, qui ne sera jamais inliné par le JIT. Le même code en C++/CLI produira un accessor de 20 octets, qui sera inliné par le JIT.
un autre exemple est les variables temporaires, qui sont simplement compilées par le compilateur C++ tout en étant mentionnées dans le IL produit par le compilateur C#. L'optimisation de la compilation statique C++ se traduira par moins de code, ce qui autorise une optimisation JIT plus agressive, encore une fois.
la raison de cela a été spéculé pour être le fait c++/CLI compilateur profité des techniques d'optimisation vastes de C++ compilateur natif.
Conclusion
j'aime le C++.
mais pour autant que je le vois, C# ou Java sont tous dans l'ensemble un meilleur pari. Pas parce qu'ils sont plus rapides que C++, mais parce que quand vous additionnez leurs qualités, ils finissent par être plus productifs, ont besoin de moins de formation, et ont des bibliothèques standards plus complètes que C++. Et comme pour la plupart des programmes, leurs différences de vitesse (d'une façon ou d'une autre) seront négligeables...
Modifier (2011-06-06)
Mon expérience sur C#/.NET
j'ai maintenant 5 mois de codage professionnel presque exclusif C# à mon CV déjà plein de C++ et Java, et une touche de C++/CLI).
j'ai joué avec WinForms (Ahem...) et WCF (cool!), et WPF (Cool!!!! Par le biais de XAML et de raw C#. WPF est si facile, je crois Balancer juste ne peut pas le comparer à elle), et de C# 4.0.
la conclusion est que s'il est plus facile/plus rapide de produire un code qui fonctionne en C#/Java qu'en C++, il est beaucoup plus difficile de produire un code fort, sûr et robuste en C# (et encore plus dur en Java) qu'en C++. Les raisons abondent, mais elles peuvent être résumées comme suit:
- les Génériques ne sont pas aussi puissants que les modèles ( essayer d'écrire un efficace générique de la méthode Parse (à partir de la chaîne de T), ou un efficace équivalent de boost::lexical_cast en C# pour comprendre le problème )
- RAII reste inégalée ( GC peut toujours en fuite (oui, j'ai eu à gérer ce problème) et ne manipule que la mémoire. Même
using
de C#n'est pas aussi facile et puissant car écrire une implémentation correcte de disposition est difficile ) - C#
readonly
et Javafinal
ne sont nulle part aussi utiles que C++'sconst
( il n'y a pas moyen d'exposer des données complexes en lecture seule (un arbre de nœuds, par exemple) dans C# sans travail énorme, alors que c'est une fonctionnalité intégrée de C++. Données immuables est un intéressant solution, mais tout ne peut pas être rendu immuable, donc ce n'est même pas assez, de loin ).
donc, C# reste un langage agréable tant que vous voulez quelque chose qui fonctionne, mais un langage frustrant le moment où vous voulez quelque chose que toujours et en toute sécurité fonctionne.
Java est encore plus frustrant, car il a les mêmes problèmes que C#, et plus encore: manquant l'équivalent de C# ' S using
mot-clé, un un collègue très compétent a passé trop de temps à s'assurer que ses ressources étaient correctement libérées, alors que L'équivalent en C++ aurait été facile (en utilisant des destructeurs et des pointeurs intelligents).
donc je suppose que le gain de productivité de C#/Java est visible pour la plupart des codes... jusqu'au jour où vous avez besoin du code pour être aussi parfait que possible. Ce jour-là, tu connaîtras la douleur. (vous n'allez pas croire ce qui est demandé à partir de notre serveur et applications GUI...).
à propos de Java et C++
j'ai gardé le contact avec les équipes serveurs (j'ai travaillé 2 ans parmi eux, avant de revenir à L'équipe GUI), de l'autre côté du bâtiment, et j'ai appris quelque chose d'intéressant.
ces dernières années, la tendance était de faire en sorte que les applications Java server soient destinées à remplacer les anciennes applications c++ server, car Java dispose de nombreux cadres/outils, et est facile à entretenir, déployer, etc. etc..
...Jusqu'à ce que le problème de la faible latence une tête moche ces derniers mois. Ensuite, les applications Java server, peu importe l'optimisation tentée par notre équipe Java qualifiée, ont simplement et proprement perdu la course contre l'ancien serveur C++, pas vraiment optimisé.
actuellement, la décision est de garder les serveurs Java pour un usage courant où la performance tout en restant important, n'est pas concerné par l'objectif de faible latence, et d'optimiser agressivement les applications serveur c++ déjà plus rapide pour les besoins de faible latence et ultra-faible latence.
Conclusion
Rien n'est aussi simple que prévu.
Java, et encore plus C#, sont des langages cools, avec des bibliothèques et des cadres standards étendus, où vous pouvez coder rapidement, et ont résultat très bientôt.
mais quand vous avez besoin de puissance brute, des optimisations puissantes et systématiques, un support de compilateur solide, des fonctionnalités linguistiques puissantes et une sécurité absolue, Java et C# rendent difficile de gagner le dernier les pourcentages manquants mais critiques de la qualité vous devez rester au-dessus de la concurrence.
c'est comme si vous aviez besoin de moins de temps et moins de développeurs expérimentés en C#/Java qu'en C++ pour produire du code de qualité moyenne, mais d'un autre côté, au moment où vous aviez besoin d'un code de qualité excellent pour parfaire, il était soudainement plus facile et plus rapide d'obtenir les bons résultats en C++.
bien sûr, c'est ma propre perception, peut-être limitée à nos besoins spécifiques.
mais tout de même, c'est ce qui se passe aujourd'hui, à la fois dans les équipes GUI et les équipes côté serveur.
bien sûr, je vais mettre à jour ce post si quelque chose de nouveau arrive.
Modifier (2011-06-22)
"nous trouvons qu'en ce qui concerne la performance, C++ gagne par une grande marge. Toutefois, il a également exigé le plus vaste efforts d'ajustement, dont beaucoup ont été réalisés à un niveau de sophistication qui ne serait pas disponible pour le programmeur moyen.
[...] La version Java était probablement la plus simple à mettre en œuvre, mais la plus difficile à analyser en termes de performances. En particulier, les effets autour de la collecte des ordures étaient compliqués et très difficiles à régler."
Sources:
- https://days2011.scala-lang.org/sites/days2011/files/ws3-1-Hundt.pdf
- http://www.computing.co.uk/ctg/news/2076322/-winner-google-language-tests
Modifier (2011-09-20)
"Le mot sur Facebook est qu' raisonnablement écrit en C++ code s'exécute rapidement, " qui souligne l'énorme effort consacré à l'optimisation de PHP et du code Java. Paradoxalement, le code C++ est plus difficile à écrire que dans d'autres langues, mais code efficace est beaucoup plus facile [pour écrire en C++ que dans d'autres langues]. "
– Herb Sutter à / / build / , citant Andrei Alexandrescu
Sources:
chaque fois que je parle de performance gérée ou non gérée, j'aime à souligner la série Rico (et Raymond) a comparé C++ et C# versions d'un dictionnaire chinois/anglais. Ce recherche google vous permettra de lire par vous-même, mais j'aime le résumé de Rico.
alors j'ai honte de ma défaite écrasante? Guère. Le code géré a obtenu un très bon résultat pour pratiquement aucun effort. De défaite le Raymond dirigé a dû:
- Écrire son propre fichier I/O trucs
- écrire sa propre classe de cordes
- écrire son propre allocator
- écrire sa propre carte internationale
bien sûr, il a utilisé disponibles plus bas les bibliothèques de niveau pour faire ça, mais c'est encore beaucoup de travail. Pouvez-vous appeler qu'est-ce qui reste d'un programme STL? Je n'ai pas pensez donc, je pense qu'il a gardé l' std:: classe de vecteur qui a finalement été jamais un problème et il a gardé la trouvaille fonction. Pratiquement tout le reste est allé.
donc, yup, vous pouvez definately battre le CLR. Raymond peut faire tourner son programme encore plus rapide je pense.
fait intéressant, le temps de fichier tel que rapporté par les deux programmes temporisateurs internes est d'environ la même -- 30ms pour chaque. La différence est dans généraux.
pour moi l'essentiel est qu'il il a fallu 6 révisions pour la version non gérée pour battre la version gérée qui était un port simple du code original non géré. Si vous avez besoin de chaque dernière partie de performance (et avoir le temps et l'expertise pour l'obtenir), vous devrez aller sans être géré, mais pour moi, je vais prendre l'avantage de l'ordre de grandeur que j'ai sur les premières versions au-dessus du 33% que je gagne si j'essaie 6 fois.
la compilation pour des optimisations de CPU spécifiques est généralement surestimée. Il suffit de prendre un programme en C++ et compiler avec optimisation pour pentium PRO et exécuter sur un pentium 4. Puis recompiler avec optimize pour pentium 4. J'ai passé de longs après-midi à le faire avec plusieurs programmes. Résultats généraux?? Généralement moins de 2-3% d'augmentation de performance. Les avantages théoriques de JIT sont donc pratiquement nuls. La plupart des différences de performance ne peuvent être observées qu'en utilisant des fonctionnalités de traitement de données scalaires, quelque chose qui aura éventuellement besoin d'un réglage fin manuel pour atteindre une performance maximale de toute façon. Les optimisations de ce genre sont lentes et coûteuses à réaliser, ce qui les rend parfois inappropriées pour JIT de toute façon.
sur le monde réel et l'application réelle C++ est encore généralement plus rapide que java, principalement en raison d'une empreinte mémoire plus légère qui se traduit par de meilleures performances de cache.
mais pour utiliser toutes les capacités C++ vous, le développeur doit travailler dur. Vous pouvez obtenir des résultats supérieurs, mais vous devez utiliser votre cerveau pour que. C++ est un langage qui a décidé de vous présenter plus d'outils, en facturant le prix que vous devez les apprendre pour pouvoir bien utiliser le langage.
JIT (Just In Time Compiling) peut être incroyablement rapide parce qu'il optimise pour la plate-forme cible.
cela signifie qu'il peut tirer avantage de n'importe quel truc de compilateur que votre CPU peut supporter, indépendamment du CPU sur lequel le développeur a écrit le code.
Le concept de base de l' .NET JIT fonctionne comme ceci (très simplifié):
appelant pour la première fois une méthode:
- votre code de programme appelle une méthode Foo ()
- le CLR regarde le type qui implémente Foo () et obtient les métadonnées qui lui sont associées
- D'après les métadonnées, le CLR sait dans quelle adresse mémoire est stocké L'IL (code octet Intermédiaire).
- le CLR attribue un bloc de mémoire, et appelle le JIT.
- le JIT compile L'IL en code natif, le place dans la mémoire allouée, et puis modifie le pointeur de fonction dans les métadonnées de type Foo () pour pointer vers ce code natif.
- le code natif est ran.
appelant une méthode pour la deuxième fois:
- votre code de programme appelle une méthode Foo ()
- le CLR regarde le type qui implémente Foo() et trouve le pointeur de fonction dans les métadonnées.
- le code natif à ce l'emplacement de la mémoire est couru.
comme vous pouvez le voir, la deuxième fois, son pratiquement le même processus que C++, sauf avec l'avantage des optimisations en temps réel.
cela dit, il ya encore d'autres frais généraux de questions que de ralentir un langage managé, mais le JIT aide beaucoup.
j'aime Orion Adrian 's réponse, mais il est un autre aspect de l'.
la même question a été posée il y a des décennies à propos du langage de l'assemblée et des langues" humaines " comme FORTRAN. Et une partie de la réponse est similaire.
Oui, un programme C++ est capable d'être plus rapide que le C# sur tout (non-trivial?), mais le programme en C# sera souvent aussi rapide ou plus rapide qu'une implémentation" naïve " en C++, et une la version en C++ prendra plus de temps à développer, et pourrait encore battre la version en C# d'une très petite marge. Alors, est-il vraiment la peine?
vous devrez répondre à cette question sur une base individuelle.
cela dit, je suis un fan de longue date de C++, et je pense que c'est incroyablement expressif et puissant de la langue, parfois sous-estimé. Mais dans beaucoup de problèmes "réels" (pour moi personnellement, cela signifie "le genre que je suis payé pour résoudre"), C# va faire le travail plus tôt et plus sûr.
la plus grosse pénalité que tu payes? Beaucoup de programmes .net et Java sont des bogues de mémoire. J'ai vu que les applications.net et Java prennent "des centaines" de mégaoctets de mémoire, alors que les programmes C++ d'une complexité similaire effleurent à peine les "dizaines" de MBs.
Je ne suis pas sûr que vous trouverez souvent que le code Java tourne plus vite que C++, même avec Hotspot, mais je vais essayer d'expliquer comment cela pourrait se produire.
pensez au code Java compilé comme langage machine interprété pour la JVM. Lorsque le processeur Hotspot remarque que certaines pièces du code compilé vont être utilisées plusieurs fois, il effectue une optimisation du code machine. Puisque le réglage manuel de L'ensemble est presque toujours plus rapide que c++ compilé code, il est normal de comprendre que le code de la machine programmatically-tuned ne va pas être trop mauvais.
donc, pour du code hautement répétitif, je pouvais voir où il serait possible pour Hotspot JVM de faire tourner le Java plus vite que C++... jusqu'à ce que la collecte des ordures entre en jeu. :)
généralement, l'algorithme de votre programme sera beaucoup plus important pour la vitesse de votre application que le langue . Vous pouvez implémenter un mauvais algorithme dans n'importe quel langage, y compris C++. Avec cela à l'Esprit, vous serez généralement en mesure d'écrire du code plus rapidement dans un langage qui vous aide à mettre en œuvre un algorithme plus efficace.
les langues de plus haut niveau s'en sortent très bien en facilitant l'accès à de nombreuses structures de données pré-construites efficaces et des pratiques encourageantes qui vous aideront à éviter le code inefficace. Bien sûr, ils peuvent parfois aussi rendre facile d'écrire un tas de code vraiment lent, aussi, donc vous devez toujours connaître votre plate-forme.
aussi, C++ rattrape son retard avec les fonctionnalités" new " (notez les guillemets) comme les conteneurs STL, les pointeurs automatiques, etc -- voir la bibliothèque boost, par exemple. Et vous pourriez parfois trouver que le moyen le plus rapide d'accomplir une tâche nécessite une technique comme l'arithmétique des pointeurs qui est interdite dans un langage de niveau supérieur -- bien qu'ils permettent typiquement d'appeler à une bibliothèque écrite dans un langage qui peut l'implémenter comme désiré.
l'essentiel est de connaître le langage que vous utilisez, L'API qui vous est associée, ce qu'elle peut faire et ce qu'elle limite.
Je ne sais pas non plus...mes programmes Java sont toujours lents. :- ) Je n'ai jamais vraiment remarqué que les programmes C# étaient particulièrement lents.
Voici une autre référence intéressante, que vous pouvez essayer vous-même sur votre propre ordinateur.
il compare ASM, VC++, C#, Silverlight, Java applet, Javascript, Flash (AS3)
Roozz plugin vitesse de démonstration
veuillez noter que la vitesse de javascript varie beaucoup selon le navigateur qui l'exécute. La même chose est vraie pour Flash et Silverlight parce que ces plugins fonctionnent dans le même processus l'hébergement navigateur. Mais le plugin Roozz fonctionne en standard .fichiers exe, qui s'exécutent dans leur propre processus, donc la vitesse n'est pas influencée par le navigateur d'hébergement.
, Vous devez définir le "faire mieux que..". Je sais, tu as demandé pour la vitesse, mais ce n'est pas tout ce qui compte.
- Faire des machines virtuelles effectuer plus de temps d'exécution le dessus? Oui!
- mangent-ils plus de mémoire de travail? Oui!
- ont-ils des coûts de démarrage plus élevés (initialisation de l'exécution et compilateur JIT) ? Oui!
- ont-ils besoin d'une énorme bibliothèque installée? Oui!
Et ainsi de suite, son biaisée, oui ;)
avec C# et Java vous payez un prix pour ce que vous obtenez (codage plus rapide, gestion automatique de la mémoire, grande bibliothèque et ainsi de suite). Mais vous n'avez pas beaucoup de place pour marchander sur les détails: prenez le paquet complet ou rien.
même si ces langages peuvent optimiser un code pour l'exécuter plus rapidement que le code compilé, l'approche globale est (IMHO) inefficace. Imaginez conduire tous les jours 5 miles à votre lieu de travail, avec un camion! Son confort, il se sent bien, vous êtes en sécurité (extreme crumple zone) et après que vous marchez sur l'essence pendant un certain temps, il sera même aussi rapide qu'une voiture standard! Pourquoi n'avons-nous pas tous un camion pour aller au travail? ;)
En C++, vous obtenez ce que vous payez, pas plus, pas moins.
citant Bjarne Stroustrup: "C++ est mon langage de collecte de déchets préféré parce qu'il génère si peu de déchets" texte du lien
le code exécutable produit à partir d'un compilateur Java ou C# n'est pas interprété -- il est compilé en code natif" just in time " (JIT). Ainsi, le premier code de temps dans un programme Java/c# est rencontré pendant l'exécution, il y a une certaine surcharge pendant que le "compilateur d'exécution" (alias compilateur JIT) transforme le code octet (Java) ou le code IL (C#) en instructions Machine natives. Cependant, la prochaine fois que le code est rencontré lors de l'application est toujours en cours d'exécution, le code natif est exécuté immédiatement. Cela explique comment certains programmes Java / C# semblent être lents au départ, mais fonctionnent mieux plus ils s'exécutent. Un bon exemple est ASP.Net site web. La première fois que le site web est consulté, il peut être un peu plus lent car le code C# est compilé en code natif par le compilateur JIT. Les accès subséquents se traduisent par un site web beaucoup plus rapide -- mise en cache côté serveur et côté client.
quelques bonnes réponses à la question que vous avez posée. J'aimerais prendre du recul et regarder la situation dans son ensemble.
gardez à l'esprit que la perception de votre utilisateur de la vitesse du logiciel que vous écrivez est affectée par beaucoup d'autres facteurs que la façon dont le codegen optimise. Voici quelques exemples:
-
gestion manuelle de la mémoire est difficile à faire correctement (pas de fuites), et encore plus difficile à faire efficacement (libre mémoire peu de temps après vous avez terminé avec elle). L'utilisation d'un GC est, en général, plus susceptible de produire un programme qui gère bien la mémoire. Êtes-vous prêt à travailler très fort et à retarder la livraison de votre logiciel pour tenter de dépasser le GC?
-
mon C# est plus facile à lire et à comprendre que mon C++. J'ai aussi d'autres moyens de me convaincre que mon code C# fonctionne correctement. Cela signifie que je peux optimiser mes algorithmes avec moins de risque d'introduire des bogues (et les utilisateurs n'aiment pas les logiciels qui craquent, même s'ils le font rapidement!)
-
je peux créer mon logiciel plus rapidement en C# qu'en C++. Cela libère du temps pour travailler sur la performance, et toujours livrer mon logiciel à temps.
-
il est plus facile d'écrire de bonnes UI en C# que C++, donc je suis plus susceptible d'être en mesure de mettre le travail à l'arrière-plan pendant que L'UI reste réactif, ou de fournir des progrès ou des prestations D'assurance-chômage quand le programme a pour bloquer pendant un certain temps. Cela ne rend rien plus rapide, mais il rend les utilisateurs plus heureux d'attendre.
Tout ce que j'ai dit sur C# est probablement vrai pour Java, je n'ai pas l'expérience pour le dire avec certitude.
si vous êtes un programmeur Java/C# apprenant le C++, vous serez tenté de garder la pensée en termes de Java/C# et traduire mot à mot à la syntaxe c++. Dans ce cas, vous obtenez seulement les avantages mentionnés plus haut du code natif vs. interpreted/JIT. Pour obtenir le plus grand gain de performance en C++ par rapport à Java/C#, vous devez apprendre à penser en C++ et à concevoir du code spécifiquement pour exploiter les forces de C++.
pour paraphraser Edsger Dijkstra : [votre première langue] mutile l'esprit au-delà de la récupération.
Pour paraphraser Jeff Atwood : vous pouvez écrire [votre langue maternelle] dans n'importe quelle nouvelle langue.
L'une des optimisations JIT les plus significatives est la méthode inlining. Java peut même les méthodes virtuelles en ligne si cela peut garantir l'exactitude de l'exécution. Ce type d'optimisation ne peut généralement pas être effectué par des compilateurs statiques standard car il nécessite une analyse de programme entier, ce qui est difficile en raison de la compilation séparée (en revanche, JIT a tout le programme disponible pour lui). La méthode inlining améliore d'autres optimisations, donnant des blocs de code plus grands à optimiser.
L'allocation de mémoire Standard en Java / c# est aussi plus rapide, et la deallocation (GC) n'est pas beaucoup plus lente, mais seulement moins déterministe.
il est peu probable que les langages machines virtuels surpassent les langages compilés, mais ils peuvent se rapprocher suffisamment pour que cela n'ait pas d'importance, pour (au moins) les raisons suivantes (je parle pour Java ici puisque je n'ai jamais fait C#).
1 / L'environnement Java Runtime est généralement capable de détecter des morceaux de code qui sont exécutés fréquemment et d'effectuer une compilation juste à temps (JIT) de ces sections de sorte qu'à l'avenir, elles s'exécutent à la vitesse maximale compilée.
2 / de vastes parties des bibliothèques Java sont compilées de sorte que, lorsque vous appelez une fonction de bibliothèque, vous exécutez du code compilé, non interprété. Vous pouvez voir le code (en C) en téléchargeant L'OpenJDK.
3 / A moins que vous ne fassiez des calculs massifs, la plupart du temps votre programme est en cours d'exécution, il attend les données d'un humain très lent (relativement parlant).
4 / Puisqu'une grande partie de la validation du bytecode Java est faite au moment de en chargeant la classe, les frais généraux normaux des vérifications de fonctionnement sont considérablement réduits.
5 / dans le pire des cas, le code à forte intensité de performance peut être extrait vers un module compilé et appelé depuis Java (voir JNI) de sorte qu'il tourne à pleine vitesse.
en résumé, le bytecode Java ne sera jamais plus performant que le langage machine natif, mais il y a des moyens d'atténuer cela. Le grand avantage de Java (comme je le vois) est le énorme bibliothèque standard et le croix-plate-forme de la nature.
Orion Adrian , permettez-moi d'inverser votre post pour voir à quel point vos remarques sont infondées, parce que beaucoup de choses peuvent être dites sur C++ aussi. Et dire que le compilateur Java / C # optimize away empty functions vous donne vraiment l'impression que vous êtes et non mon expert en optimisation, parce que A) pourquoi un vrai programme devrait-il contenir des fonctions vides, à l'exception d'un très mauvais code d'héritage, b) qui n'est pas vraiment une optimisation de bord noir et saignant.
mis à part cette phrase, vous avez parlé ouvertement de pointeurs, mais les objets en Java et C# ne fonctionnent-ils pas comme des pointeurs C++? Puissent-ils ne pas se chevauchent? Puissent-ils ne pas être null? C (et la plupart des implémentations C++) a le mot-clé restrict, les deux ont des types de valeur, C++ A LA référence à la valeur avec garantie non-null. Qu'offrent Java et C#?
>>>>>>>>>>
généralement, C et c++ peuvent être aussi rapides ou plus rapides parce que le compilateur AOT -- a compilateur qui compile votre code avant le déploiement, une fois pour toutes, sur votre serveur de construction de base de mémoire élevée -- peut faire des optimisations qu'un programme compilé C# ne peut pas parce qu'il a une tonne de temps pour le faire. Le compilateur peut déterminer si la machine est Intel ou AMD; Pentium 4, Core Solo, ou Core Duo; ou si elle prend en charge SSE4, etc, et si votre compilateur ne prend pas en charge runtime dispatch, vous pouvez le résoudre vous-même en déployant une poignée de binaires spécialisés.
A C # program est généralement compilé lors de son exécution de sorte qu'il fonctionne correctement sur toutes les machines, mais n'est pas optimisé autant qu'il pourrait l'être pour une seule configuration (c.-à-d. processeur, jeu d'instruction, autre matériel), et il doit passer un certain temps en premier. Les fonctionnalités telles que la fission de boucle, l'inversion de boucle, la vectorisation automatique, l'optimisation de programme entier, l'expansion de modèle, IPO, et beaucoup plus, sont très difficiles à résoudre tout et complètement d'une manière qui ne dérange pas la fin utilisateur.
en outre, certaines fonctionnalités de langage permettent au compilateur en C++ ou en C de faire des suppositions sur votre code qui lui permettent d'optimiser certaines parties loin qui ne sont tout simplement pas sécuritaires pour le compilateur Java/C# à faire. Lorsque vous n'avez pas accès à l'id de type complet des génériques ou un flux de programme garanti, Il ya beaucoup d'optimisations qui ne sont tout simplement pas sûrs.
aussi C++ et C font beaucoup d'allocations de pile à la fois avec juste une incrémentation de registre, ce qui est sûrement plus efficace que les attributions Javas et C# quant à la couche d'abstraction entre le collecteur d'ordures et votre code.
maintenant je ne peux pas parler pour Java sur ce prochain point, mais je sais que C++ Compilateurs par exemple va effectivement supprimer les méthodes et les appels de méthode quand il sait que le corps de la méthode est vide, il va éliminer les sous-expressions communes, il peut essayer et réessayer pour trouver l'utilisation optimale de registre, il ne fait pas de vérification des limites, il va autovectorize les boucles et les boucles intérieures et invertira de l'intérieur à l'extérieur, il déplace les conditionnels hors des boucles, il divise et unsplits les boucles. Il va étendre std:: vecteur en natif zero tableaux aériens que vous feriez Le C. Il fera des optimmisations inter procédurales. Il établira les valeurs de retour directement sur le site de l'appelant. Il se plie et propage des expressions. Il va réorganiser les données dans un cache de manière conviviale. Il va faire sauter le filetage. Il vous permet d'écrire des traceurs de temps de compilation avec zéro gestion d'exécution. Il fera des optimisations basées sur des graphes très chères. Il fera la réduction de la force, s'il remplace certains codes avec syntaxiquement totalement inégal mais sémantiquement équivalent code (l'ancien "XOR foo, foo" est juste le plus simple, bien que l'optimisation périmée d'une telle sorte). Si vous le demandez gentiment, vous pouvez omettre les standards IEEE floating point et permettre encore plus d'optimisations comme l'operand floating point re-ordering. Après qu'il a massé et massacré votre code, il pourrait répéter l'ensemble du processus, parce que souvent, certaines optimisations jettent les bases même de certaines optimisations. Il pourrait également juste réessayer avec des paramètres déplacés et voir comment l'autre variante marque dans son classement interne. Et il utilisera ce genre de logique tout au long de votre code.
comme vous pouvez le voir, il y a beaucoup de raisons pour lesquelles certaines implémentations C++ ou c seront plus rapides.
maintenant tout cela dit, de nombreuses optimisations peuvent être faites en C++ qui soufflez loin de tout ce que vous pourriez faire avec C#, en particulier dans le nombre crunching, temps réel et proche du métal Royaume, mais pas exclusivement là. Vous n'avez même pas besoin de toucher un seul pointeur pour venir un long chemin.
alors, selon ce que vous écrivez, j'irais avec l'un ou l'autre. Mais si vous écrivez quelque chose qui n'est pas dépendant du matériel (pilote, jeu vidéo, etc), Je ne m'inquiéterais pas de la performance de C# (encore une fois je ne peux pas parler de Java). Il va faire tout aussi bien.
<<<<<<<<<<
en général, certains arguments généralisés peuvent sembler cool dans certains billets, mais ne semblent pas généralement crédibles.
de toute façon, pour faire la paix: AOT est grande, de même que JIT . La seule réponse correcte peut être: cela dépend. Et les vraies personnes intelligentes savent que vous pouvez utiliser le meilleur des deux mondes de toute façon.
cela ne se produirait que si L'interpréteur Java produisait du code machine qui est en fait meilleur optimisé que le code machine que votre compilateur génère pour le code C++ que vous écrivez, au point où le code C++ est plus lent que le code Java et le coût d'interprétation.
cependant, les chances que cela se produise sont assez faibles - à moins que Java n'ait une bibliothèque très bien écrite, et que vous ayez votre propre c++mal écrit. bibliothèque.
en fait, C# ne fonctionne pas vraiment sur une machine virtuelle comme Java. IL est compilé en langage assembleur, qui est entièrement du code natif et tourne à la même vitesse que le code natif. Vous pouvez pré-lancer une application .NET qui supprime entièrement le coût JIT et ensuite vous exécutez entièrement du code natif.
le ralentissement avec .NET viendra non pas parce que .NET code est plus lent, mais parce qu'il fait beaucoup plus dans les coulisses pour faire des choses comme collecte des ordures, vérifier références, stocker les cadres complets de la pile,etc. Cela peut être très puissante et très utile lors de la construction d'applications, mais aussi un coût. Notez que vous pouvez faire toutes ces choses dans un programme C++ aussi bien (une grande partie du noyau de la fonctionnalité .NET est en fait du code .NET que vous pouvez voir dans ROTOR). Cependant, si vous avez écrit à la main la même fonctionnalité, vous finiriez probablement avec un programme beaucoup plus lent puisque L'exécution.net a été optimisée et finement ajustée.
cela dit, on les points forts de code managé est qu'il peut être entièrement vérifiables, c'est à dire. vous pouvez vérifier que le code n'accèdera jamais à la mémoire d'un autre processus ou ne fera rien de spécial avant de l'exécuter. Microsoft a un prototype de recherche d'un système d'exploitation entièrement géré qui a montré de façon surprenante qu'un environnement géré à 100% peut en fait effectuer beaucoup plus rapidement que n'importe quel système d'exploitation moderne en profitant de cette vérification pour désactiver les caractéristiques de sécurité qui ne sont plus nécessaires programmes gérés (nous parlons comme 10x dans certains cas). SE radio a un super épisode qui parle de ce projet.
dans certains cas, le code géré peut être plus rapide que le code natif. Par exemple, les algorithmes de collecte des ordures" mark-and-sweep " permettent à des environnements comme le JRE ou le CLR de libérer un grand nombre d'objets de courte durée (généralement) en une seule passe, où la plupart des objets c/c++ heap sont libérés un à la fois.
à Partir de wikipedia :
pour de nombreuses raisons pratiques, les algorithmes d'allocation/deallocation-intensive mis en œuvre dans les langages de collecte des ordures peuvent en fait être plus rapides que leurs équivalents en utilisant l'allocation manuelle de tas. L'une des principales raisons en est que le collecteur d'ordures permet au système d'écoulement d'amortir les opérations d'allocation et de désallocation d'une manière potentiellement avantageuse.
cela dit, j'ai écrit beaucoup de C# et beaucoup de C++, et j'ai beaucoup de points de référence. Dans mon expérience, C++ est beaucoup plus rapide que C#, de deux façons: (1) si vous prenez un code que vous avez écrit en C#, le port vers C++ le code natif tend à à être plus rapide. Comment beaucoup plus rapide? Ça varie beaucoup, mais il n'est pas rare de voir une amélioration de 100% de la vitesse. (2) dans certains cas, la collecte des ordures peut massivement ralentir une application gérée. Le .NET CLR fait un travail terrible avec de grands tas (disons, > 2 Go), et peut finir par passer beaucoup de temps au GC--même en applications qui ont peu,voire pas d'objets de durée de vie intermédiaire.
bien sûr, dans la plupart des cas que j'ai rencontrés, les langages managés sont assez rapides, de loin, et le compromis de maintenance et de codage pour la performance supplémentaire de C++ n'est tout simplement pas un bon compromis.
en fait, le JVM HotSpot de Sun utilise l'exécution en mode mixte. Il interprète le bytecode de la méthode jusqu'à ce qu'il détermine (généralement à travers un compteur d'une certaine sorte) qu'un bloc particulier de code (méthode, boucle, bloc try-catch, etc.) va être exécuté beaucoup, alors il JIT compile. Le temps requis pour compiler une méthode JIT prend souvent plus de temps que si la méthode devait être interprétée si c'est une méthode rarement exécutée. Les performances sont généralement plus élevées pour le "mode mixte" parce que la JVM ne perdre du temps à déchiffrer un code qui est rarement, voire jamais, exécuté. C# et .NET ne font pas cela. .NET jette tout ce qui, souvent, fait perdre du temps.
allez lire à propos de HP Labs' Dynamo , un interpréteur pour PA-8000 qui fonctionne sur PA-8000, et exécute souvent des programmes plus rapidement qu'ils ne le font nativement. Alors ça ne sera pas du tout surprenant!
ne le voyez pas comme une" étape intermédiaire " -- exécuter un programme implique déjà beaucoup d'autres étapes, dans n'importe quelle langue.
il revient souvent à:
-
les programmes ont des points chauds, donc même si vous êtes plus lent à exécuter 95% du corps de code que vous avez à exécuter, vous pouvez toujours être compétitif si vous êtes plus rapide à la chaude 5%
-
un HLL en sait plus sur votre intention qu'un LLL comme C/C++, et peut donc générer plus de code optimisé (OCaml a encore plus, et dans la pratique est souvent encore plus rapide)
-
un compilateur JIT a beaucoup d'informations qu'un compilateur statique n'a pas (comme les données réelles il vous arrive d'avoir cette fois)
-
un compilateur JIT peut faire des optimisations à l'exécution que les linkers traditionnels ne sont pas vraiment autorisés à faire (comme réorganiser des branches de sorte que le cas commun est plat, ou inlining appels de bibliothèque)
dans l'ensemble, C / C++ sont des langages assez mauvais pour la performance: il y a relativement peu d'informations sur vos types de données, pas d'informations sur vos données, et pas d'exécution dynamique pour permettre à beaucoup de la manière de l'optimisation du temps.
vous pourriez obtenir de courtes sursauts quand Java ou CLR est plus rapide que C++, mais dans l'ensemble la performance est pire pour la vie de l'application: voir www.codeproject.com/KB/dotnet/RuntimePerformance.aspx pour quelques résultats.
Voici la réponse de Cliff Click: http://www.azulsystems.com/blog/cliff/2009-09-06-java-vs-c-performanceagain
ma compréhension est que C/C++ produit du code natif pour fonctionner sur une architecture de machine particulière. À l'inverse, des langages comme Java et C# s'exécutent sur une machine virtuelle qui fait abstraction de l'architecture native. Logiquement, il semble impossible pour Java ou C# de correspondre à la vitesse de C++ à cause de cette étape intermédiaire, mais on m'a dit que les derniers compilateurs ("hot spot") peuvent atteindre cette vitesse ou même la dépasser.
C'est illogique. L'utilisation d'une représentation intermédiaire ne sont pas intrinsèquement de dégrader les performances. Par exemple, llvm-gcc compile C et C++ via LLVM IR (qui est une machine virtuelle à enregistrement infini) en code natif et il obtient d'excellentes performances (souvent en battant GCC).
C'est peut-être plus une question de compilateur qu'une question de langue, mais est-ce que n'importe qui peut expliquer en anglais simple comment il est possible pour l'un de ces langages de machine virtuels de mieux performer qu'une langue maternelle?
voici quelques exemples:
-
les machines virtuelles avec la compilation JIT facilitent la génération de code d'exécution (par exemple
System.Reflection.Emit
sur .NET) de sorte que vous pouvez compiler le code généré à la volée dans des langages comme C# et F# mais devez recourir à l'écriture d'un interpréteur relativement lent en C ou C++. Par exemple, pour implémenter des expressions régulières. -
les parties de la machine virtuelle (par exemple la barrière d'écriture et l'allocateur) sont souvent écrites en assembleur codé à la main parce que C et C++ ne génèrent pas assez de code. Si un programme souligne ces parties d'un système, alors il pourrait surpasser tout ce qui peut être écrit en C ou C++.
-
la liaison Dynamique de code natif exige la conformité à une ABI qui peut gêner la performance et évite tout-optimisation du programme alors que la liaison il est généralement différé sur VMs et peut bénéficier d'optimisations globales du programme (comme reified generics de.Net).
j'aimerais également aborder certains problèmes avec la réponse très controversée de paercebal ci-dessus (parce que quelqu'un continue de supprimer mes commentaires sur sa réponse) qui présente une vue polarisée contre-productive:
le traitement du code sera effectué au moment de la compilation...
Par conséquent, la métaprogrammation de template ne fonctionne que si le programme est disponible au moment de la compilation, ce qui n'est souvent pas le cas, par exemple, il est impossible d'écrire une bibliothèque d'expressions régulières performante dans vanilla C++ parce qu'elle est incapable de générer du code à l'exécution (un aspect important de la métaprogrammation).
...jouer avec les types se fait au moment de la compilation...L'équivalent en Java ou C# est au mieux douloureux à écrire, et sera toujours plus lent et résolu à l'exécution même lorsque les types sont connus au moment de la compilation.
En C#, c'est seulement vrai pour les types de référence et n'est pas vrai pour les types de valeur.
peu importe l'optimisation JIT, rien ne va avoir un accès rapide comme pointeur direct à la mémoire...si vous avez des données contiguës en mémoire, accédez-les par des pointeurs C++ (c.-à-d. des pointeurs C)... Donnons à César son dû) va des fois plus vite Qu'en Java / C#.
les gens ont observé Java battre C++ sur le test SOR de la référence SciMark2 précisément parce que les pointeurs empêchent les optimisations liées à l'alias.
vaut également la peine de noter que .NET ne se spécialise pas dans les génériques à travers les bibliothèques dynamiquement liées après avoir créé un lien, alors que C++ Ne le peut pas parce que les modèles doivent être résolus avant de créer un lien. Et évidemment le grand avantage des génériques ont sur les gabarits est des messages d'erreur compréhensibles.
en plus de ce que d'autres ont dit, d'après ce que j'ai compris .NET et Java sont meilleurs à l'allocation de mémoire. Par exemple: ils peuvent compacter la mémoire au fur et à mesure qu'elle se fragmente tandis que C++ Ne le peut pas (nativement, mais il le peut si vous utilisez un collecteur de déchets intelligent).
pour tout ce qui a besoin de beaucoup de vitesse, la JVM appelle simplement une implémentation C++, donc c'est une question plus de savoir si leurs lib sont bonnes que de savoir si la JVM est bonne pour la plupart des choses liées au système D'exploitation. La collecte des ordures vous coupe la mémoire en deux, mais l'utilisation de certaines des fonctionnalités STL et Boost aura le même effet, mais avec plusieurs fois le potentiel de bug.
si vous utilisez simplement des bibliothèques C++ et beaucoup de ses fonctionnalités de haut niveau dans un grand projet avec de nombreuses classes, vous va probablement finir plus lentement que d'utiliser une JVM. Sauf beaucoup plus sujettes à erreur.
cependant, L'avantage de C++ est qu'il vous permet de vous optimiser, sinon vous êtes coincé avec ce que le compilateur/jvm fait. Si vous créez vos propres conteneurs, écrivez votre propre gestion de mémoire qui est alignée, utilisez SIMD, et passez à assembler ici et là, vous pouvez accélérer au moins 2x-4x fois ce que la plupart des compilateurs C++ feront par eux-mêmes. Pour certaines opérations, 16x-32x. Qui utilise le mêmes algorithmes, si vous utilisez de meilleurs algorithmes et paralléliser, les augmentations peuvent être dramatiques, parfois des milliers de fois plus rapide que les méthodes couramment utilisées.
je le regarde à partir de quelques points différents.
- étant donné le temps et les ressources infinis, le code géré ou non sera-t-il plus rapide? De toute évidence, la réponse est que le code non géré peut toujours au moins égaler le code géré à cet égard - comme dans le pire des cas, vous auriez juste code dur la solution de code géré.
- Si vous prenez un programme dans une langue, et de traduire directement à un autre, combien pire il effectuer? Sans doute beaucoup, pour tout deux langues. La plupart des langues nécessitent des optimisations différentes et avoir différentes de pièges. Micro-performance est souvent beaucoup sur la connaissance de ces détails.
- étant donné le temps et les ressources limités, laquelle des deux langues produira un meilleur résultat? C'est la question la plus intéressante, car bien qu'une langue gérée puisse produire un code légèrement plus lent (étant donné un programme raisonnablement écrit pour cette langue), cette version sera probablement faite plus tôt, permettre plus de temps consacré à l'optimisation.
une réponse très courte: avec un budget fixe, vous obtiendrez une application java plus performante qu'une application C++ (compte tenu du retour sur investissement). en outre, la plate-forme Java dispose de profileurs plus décents, ce qui vous aidera à repérer vos points chauds plus rapidement