une. Quelle est la vitesse actuelle de Java par rapport à C ++?
Difficile à mesurer. Il est à noter qu'une grande partie de la vitesse d'une implémentation, c'est l'allocateur de mémoire, sont des algorithmes très différents en Java et en C ++. La nature non déterministe du collecteur rend extrêmement difficile l'obtention de données de performances significatives par rapport à la gestion déterministe de la mémoire en C ++, car on ne peut jamais être sûr de l'état du collecteur. Cela signifie qu'il est très difficile d'écrire un point de repère cela pourrait les comparer de manière significative. Certains modèles d'allocation de mémoire fonctionnent beaucoup plus rapidement avec un CPG, d'autres beaucoup plus rapidement avec un allocateur natif.
Ce que je dirais cependant, c'est que le CPG Java doit fonctionner rapidement dans toutes les situations. Cependant, un allocateur natif peut être remplacé par un autre plus approprié. J'ai récemment répondu à une question sur le SO sur les raisons pour lesquelles un C # Dictionary
pouvait s'exécuter (0,45 ms sur ma machine) par rapport à un programme équivalent.std::unordered_map
qui a exécuté sur (10ms sur ma machine). Cependant, en échangeant simplement l'allocateur et le hachoir par d'autres plus appropriés, j'ai réduit le temps d'exécution à 0,34 ms sur ma machine, soit un trentième du temps d'exécution d'origine. Vous ne pouvez jamais, jamais espérer réaliser ce type d'optimisation personnalisée avec Java. Le filetage est un excellent exemple de ce qui peut faire une réelle différence. Les bibliothèques de threads natives telles que TBB fournissent des allocateurs de mise en cache de threads beaucoup plus rapides que les allocateurs traditionnels lorsqu'ils traitent de nombreuses allocations sur plusieurs threads.
Maintenant, beaucoup de gens vont parler des améliorations de JIT et de la façon dont cette dernière a plus d'informations. Bien sûr, c'est vrai. Mais ce n'est toujours pas très proche de ce qu'un compilateur C ++ peut tirer, car le compilateur dispose, quant à lui, d'un temps et d'une espace infinis dans lesquels s'exécuter, du point de vue de l'exécution du programme final. Chaque cycle et chaque octet dépensé par le JIT pour réfléchir à la meilleure façon d’optimiser votre programme est un cycle que votre programme ne dépense pas en exécution et ne peut pas être utilisé pour ses propres besoins en mémoire.
En outre, il y aura toujours des moments où les optimisations du compilateur et de JIT ne pourront pas prouver certaines optimisations, en particulier dans le cas d'analyses d'échappement. En C ++, comme la valeur est de toute façon sur la pile , le compilateur n'a pas besoin de l'exécuter. De plus, il y a des choses simples, comme la mémoire contiguë. Si vous allouez un tableau en C ++, vous allouez un seul tableau contigu. Si vous allouez un tableau en Java, il n'est pas du tout contigu, car il est uniquement rempli de pointeurs qui peuvent pointer n'importe où. Il ne s’agit pas uniquement d’une surcharge de mémoire et de temps pour les doubles indirections, mais également d’une surcharge de cache. Ce genre de choses est où la sémantique de langage de Java oblige simplement à être plus lent que le code C ++ équivalent.
En fin de compte, mon expérience personnelle est que Java pourrait être environ deux fois plus rapide que le C ++, en moyenne. Cependant, il est pratiquement impossible de sauvegarder une déclaration de performance sans une suite de tests extrêmement complète, en raison des algorithmes fondamentalement différents impliqués.
b. Serait-il possible de créer un titre AAA moderne en utilisant Java?
Je suppose que vous voulez dire "jeu", ici, et pas une chance. Premièrement, il vous faudrait tout écrire vous-même, presque toutes les bibliothèques existantes et l'infrastructure cible C ++. Tout en ne le rendant pas impossible en soi, il pourrait certainement contribuer solidement au non réalisable. Deuxièmement, même les moteurs C ++ peuvent difficilement s’adapter aux contraintes de mémoire des consoles existantes, même si des machines virtuelles existent pour ces consoles, et les joueurs sur PC en attendent un peu plus pour leur mémoire. Créer des jeux AAA performants est déjà assez difficile en C ++, je ne vois pas comment cela pourrait être réalisé en Java. Personne n'a jamais écrit un jeu AAA avec un temps considérable passé dans un langage non compilé. Plus que cela, ce serait simplement extrêmement sujet aux erreurs. La destruction déterministe est essentielle pour traiter, par exemple, des ressources GPU - et en Java, vous
c. Dans quels domaines spécifiquement Java est-il plus lent que C ++, voire pas du tout? (c.-à-d. des calculs, des graphiques, ou tout simplement)
J'irais certainement pour tout autour. La nature de référence imposée de tous les objets Java signifie que Java contient beaucoup plus d'indirection et de références que le C ++ - un exemple que j'ai donné précédemment avec des tableaux, mais qui s'applique également à tous les objets membres, par exemple. Lorsqu'un compilateur C ++ peut rechercher une variable membre à temps constant, un environnement d'exécution Java doit suivre un autre pointeur. Plus vous aurez d'accès, plus cela va être lent et JIT ne peut rien y faire.
Là où C ++ peut libérer et réutiliser presque instantanément une partie de la mémoire, en Java, vous devez attendre la collection. J'espère que cette partie n'a pas quitté le cache et qu'elle nécessite par conséquent plus de mémoire, ce qui réduit les performances du cache et de la pagination. Ensuite, regardez la sémantique pour des choses comme la boxe et le déballage. En Java, si vous voulez référencer un int, vous devez l'allouer dynamiquement. C'est un gaspillage inhérent comparé à la sémantique C ++.
Ensuite, vous avez le problème des génériques. En Java, vous ne pouvez utiliser des objets génériques que par héritage au moment de l'exécution. En C ++, les modèles ne génèrent littéralement aucune surcharge, ce que Java ne peut égaler. Cela signifie que tout le code générique en Java est par nature plus lent qu'un équivalent générique en C ++.
Et puis vous arrivez au comportement indéfini. Tout le monde déteste quand leur programme présente UB, et tout le monde souhaite qu'il n'existe pas. Cependant, UB permet fondamentalement des optimisations qui ne peuvent jamais exister en Java. Jetez un coup d'œil à cet article décrivant les optimisations basées sur UB. Ne pas définir le comportement signifie que les implémentations peuvent faire plus d'optimisations et réduire le code nécessaire pour vérifier les conditions qui seraient non définies en C ++ mais définies en Java.
Fondamentalement, la sémantique de Java indique qu'il s'agit d'un langage plus lent que le C ++.
Java est-il maintenant considéré comme un langage compilé ou interprété?
Cela ne correspond vraiment à aucun de ces groupes. Je dirais que géré est vraiment une catégorie distincte, bien que je dirais que c'est nettement plus comme un langage interprété qu'un langage compilé. Plus important encore, il n’ya quasiment que deux systèmes gérés majeurs, la JVM et le CLR, et lorsque vous dites «géré», cela est suffisamment explicite.
Quelles sont les principales lacunes de Java qui ont été corrigées depuis le début?
La boxe automatique et le déballage sont la seule chose que je connaisse. Les génériques résolvent certains problèmes, mais pas beaucoup.
Quelles sont les principales lacunes de Java auxquelles il n’a pas encore été remédié?
Leurs génériques sont très, très faibles. Les génériques de C # sont considérablement plus puissants - bien que, bien sûr, ni l'un ni l'autre ne soit tout à fait des modèles. La destruction déterministe est un autre manque majeur. Toute forme de fermeture / lambda est également un problème majeur. Vous pouvez oublier une API fonctionnelle en Java. Et, bien sûr, il y a toujours la question de la performance, pour les domaines qui en ont besoin.