Je fais de la programmation depuis quelques années et j’ai commencé à utiliser Java. À l’époque, j’ai trouvé de nombreuses sources prétendant que Java était un langage inférieur d’une manière ou d’une autre. Je suis bien conscient que chaque langue a ses forces et ses faiblesses, mais beaucoup de choses que j'ai lues au sujet de Java semblent être datées.
La raison la plus souvent citée pour que Java soit inférieur est qu'il est beaucoup plus lent que d'autres langages compilés de manière native, comme C ++ par exemple. De nombreuses personnes critiquent le concepteur de jeu Notch (qui a développé Minecraft) pour l’utilisation de Java en raison de son manque apparent dans le département des performances. Je sais que Java était beaucoup plus lent à l'époque, mais de nombreuses améliorations ont été apportées depuis, notamment la compilation JIT.
J'aimerais avoir des opinions objectives sur Java en tant que langage aujourd'hui. Donc, ma question a 4 parties.
Performance.
une. Quelle est la vitesse actuelle de Java par rapport à C ++?
b. Serait-il possible de créer un titre AAA moderne en utilisant Java?
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)
Java est-il maintenant considéré comme un langage compilé ou interprété?
Quelles sont les principales lacunes de Java qui ont été corrigées depuis le début?
Quelles sont les principales lacunes de Java auxquelles il n’a pas encore été remédié?
Modifier:
Juste pour clarifier les choses, je ne fais pas ce Java vs C ++, évidemment, c ++ sera en moyenne un peu plus rapide que Java. Il me faut simplement quelque chose avec lequel comparer Java en termes de maturité en tant que langage à ce stade. Depuis que c ++ existe depuis toujours, j'ai pensé que je serais un bon point de comparaison.
la source
Réponses:
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.
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
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 ++.
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.
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.
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.
la source
Je commencerai par la condition qu'il est presque impossible pour quiconque de donner un avis vraiment neutre sur les langages de programmation. Si vous connaissez assez bien deux langues pour pouvoir les commenter de manière significative, il est presque inévitable que vous préfériez l'une plutôt que l'autre. En guise d’avertissement, je préfère le C ++ à Java, qui influence sans aucun doute mes commentaires au moins dans une certaine mesure.
1a. Vitesse: la vitesse obtenue en C ++ ou en Java dépend généralement moins du langage ou de son implémentation que des compétences du ou des programmeurs qui l'utilisent. En fin de compte, le C ++ peut probablement gagner plus rapidement en vitesse, mais ce qui compte vraiment, ce sont les différences de code que vous écrivez.
1b. Oui probablement. Dans le même temps, le C ++ est déjà bien établi et je doute que la plupart des studios de jeu voient suffisamment d’avantages pour se donner la peine de passer à Java.
1c Une réponse approfondie à cette question pourrait probablement remplir un volume important. C ++ fera généralement mieux avec des ressources plus limitées. Java bénéficie davantage (par exemple) de disposer de beaucoup de mémoire "disponible".
2. L'exécution lente et la collecte des ordures lente seraient probablement les deux plus évidentes. La bibliothèque de fenêtres précoces (AWT) était assez maladroite - Swing était une amélioration majeure.
3. Verbosité. Manque de surcharge de l'opérateur. Utilisation de la collecte des ordures. Manque d'héritage multiple. Les génériques Java sont extrêmement limités par rapport aux modèles C ++.
Je devrais ajouter que certains (tous?) De ces inconvénients (en particulier l’utilisation de garbage collection, mais aussi les autres) sont considérés par beaucoup comme des avantages de Java. La seule exception possible serait sa verbosité. La situation de la verbosité s'améliore légèrement, mais vous ne voyez certainement pas très souvent les concours de golf gagnants en Java, et dans le code ordinaire, il utilise également beaucoup de code. Je soupçonne que quelques-uns au moins le voient comme plus lisible et plus compréhensible, alors cela peut probablement aussi être considéré comme un avantage.
la source
la source
Premièrement, certains contextes, mon C ++ étant très rouillé, la plupart de mes expériences avec Java sont liées à mon expérience plus récente avec C #, qui est de toute façon beaucoup plus comparative entre pommes.
1. vitesse
Je pense que la question SO explique mieux la question. Pourquoi java at-il la réputation d’être lent? mais je pense aussi que toute cette question est colorée par le blog de Jeff Atwood, Gorilla vs. Shark . Merci à Péter et Christopher.
Cela dépend des priorités des développeurs et des compétences des développeurs. De plus, différentes parties du titre peuvent nécessiter différentes choses du langage dans lequel elles sont implémentées, ce qui conduit à un environnement linguistique hétérogène.
J'ai récemment vu un certain nombre de jeux mentionnant qu'ils chargeaient un environnement Python pendant le chargement et je soupçonne que les chevaux pour les parcours sont une motivation importante si vous voulez que votre titre sorte à temps pour la saison des vacances (par exemple). .
Vous pouvez écrire du code peu performant dans n’importe quelle langue, mais certaines langues facilitent les choix judicieux, tandis que d’autres ont plus de chances de vous laisser tracter de votre propre chef . Java appartient à la première catégorie, C ++ à la dernière.
Un grand pouvoir entraîne de grandes responsabilités, comme on dit (sans parler de la possibilité de tout foirer complètement * 8 ').
2. Java est-il maintenant considéré comme un langage compilé ou interprété?
Je ne peux pas dire ce que la plupart des gens considèrent comme tel, mais beaucoup de gens connaissent la différence entre les langages compilés et interprétés, et ne vivaient plus dans une grotte depuis 20 ans, ils sauraient également que le JIT ( Just-in) -Time ) Le compilateur est une partie importante de l'écosystème Java, il est donc probablement plus probable qu'il soit considéré comme compilé ces jours-ci.
3. Quelles sont les principales lacunes de Java qui ont été corrigées depuis le début?
Je suis un converti assez récent en Java, donc j’ai peu de contexte quant à son évolution. Mais il est intéressant de noter qu'il existe des livres comme Java: The Good Parts qui cherchent à orienter les gens vers les parties du langage qui devraient être préférées de nos jours et à éloigner les gens des zones qui sont ou devraient être, obsolète.
4. Quelles sont les principales lacunes de Java auxquelles il n’a pas encore été remédié?
À mon sens, l’un des problèmes rencontrés avec Java est l’adoption lente de nouvelles fonctionnalités.
Étant arrivé à Java à partir de C # et parcourant la page de comparaison Wikipedia , voici les éléments qui me caractérisent:
Ce qui me manque dans Java, comparé au C #
Fermetures / lambdas . J'ai été vraiment déçu quand j'ai entendu que le soutien Java était repoussé à nouveau .Enfin, nous avons Closures / lambdas dans Java 8, mais le temps qu’il a fallu attester de mon affirmation concernant la lenteur de son adoption.var
) peut sembler être un sucre syntaxique, mais lorsque vous avez des types génériques complexes, cela peut rendre le code beaucoup plus clair en supprimant beaucoup de duplications inutiles.struct
sur une classe complète.Choses que je ne manque pas en Java, comparées au C #
unsafe
code. Vous devez être si prudent avec cela que j'ai rarement trouvé que cela valait la peine de faire un effort supplémentaire.Ainsi, même en comparant des pommes avec des pommes, Java est considéré comme ayant pris du retard.
Les deux autres gros problèmes que je vois avec Java sont le retard considérable à la mise en route et le fait que (pour certaines machines virtuelles), vous devez microgérer votre tas et même le tas de génération permanente . Avec C #, les applications commençaient toujours immédiatement et je n’avais jamais eu à penser au tas, car il était alloué à partir du pool de mémoire système, et non à partir d’un pool pré-alloué attribué à la machine virtuelle.
la source
Je peux vous indiquer une source pouvant aider à répondre à la première partie de votre question. Les langages de programmation shoot out http://shootout.alioth.debian.org/u64q/which-programming-languages-are-fastest.php est une très bonne source pour voir comment les langues se comparent rapidement les uns aux autres. Ils peuvent même être filtrés sur différentes catégories pour voir dans quels domaines les langues font mieux que d’autres. Java est beaucoup plus rapide qu’il ne l’était il ya plusieurs années.
la source
1) En parlant strictement de l'UX que je reçois avec Java, ça semble lent. Je ne peux pas vous dire pourquoi vraiment. Je n'ai pas encore rencontré une application de bureau basé sur Java, qui ne se sentent lent et a une alternative plus rapide non-Java. Cela étant dit, Java peut être très rapide en vitesse de calcul pure et Internet est plein de points de repère pour le prouver. Cependant, le temps de démarrage des applications Java et la réactivité de leurs interfaces graphiques n'ont pas encore été améliorés. Peut-être que vous pourriez le faire;)
En fin de compte, la vitesse n'est pas vraiment un problème. Non seulement le matériel devient de plus en plus rapide, mais la plupart des gens ne s’intéressent étonnamment pas à lui tant que le logiciel le fait, ce qu’il doit faire et le rapport temps-temps passé en interaction par rapport au temps passé en attente est raisonnable.
2) Cette distinction est devenue si floue ces derniers temps qu’elle n’a vraiment aucune valeur.
3 + 4) Il y a eu pas mal de changements en Java. Certaines personnes prétendent déjà que ces changements ont entaché la philosophie purement simpliste de Java en s'attachant à des fonctionnalités étrangères. Il est vraiment difficile de dire objectivement ce qu'est une lacune et ce qu'est une force. Pour moi, Java est inutilement bavard, restrictif et pauvre en fonctionnalités, alors que d’autres considèrent ces caractéristiques comme une agréable ambiguïté, sécurité et clarté.
Donc, bien que ce soient ces choses qui me font personnellement ne pas utiliser Java, je ne pense pas que simplement ajouter les choses qui me manquent en Java est une bonne idée. Il y a beaucoup de langages que j'aime utiliser sur la machine virtuelle Java et plier Java pour être plus proche de ceux-ci irait à l'encontre du but de Java.
C'est une question de préférence
Le problème avec Java est qu’il est conçu pour vous empêcher de vous tirer une balle dans le pied. Une noble cause, mais avec toutes les restrictions qu’elle vous impose, il n’est pas improbable que vous trébuchiez sur l’un de vos pieds, que vous ne puissiez plus vous protéger avec les mains attachées derrière le dos pour votre propre sécurité et que vous mouriez enfin, parce que tu brises ton crâne. : D
D'une certaine manière, Java était une réponse au C ++, ce qui vous donne assez de corde pour vous suspendre non seulement, mais aussi au reste du monde. C'est toute cette corde, ce qui la rend si attrayante pour les cow-boys. Toute cette liberté et tout ce pouvoir.
Donc, tout simplement, ceci est vraiment juste une question de préférence.
Cependant, le C ++ étant une alternative à Java, vous êtes libre de choisir vos propres restrictions. Ou bien vous rendre fou avec tout le contrôle que vous avez, en risquant de confondre vos pairs:
Java a choisi de ne pas proposer de surcharge des opérateurs, pour cette raison même. Bien entendu, cela empêche les utilisateurs d’obscurcir leur code en multipliant les pointeurs de fonction par des listes. Mais en même temps, cela empêche d'autres personnes d'effectuer des calculs géométriques / algébriques avec les opérateurs habituels.
(v1 * v2 / scale) + (v3 * m)
est vraiment beaucoup plus clair quev1.multiply(v2).divide(scale).add(v3.multiply(m))
. Je vois pourquoi cela peut rebuter les personnes qui travaillent avec des graphiques et des calculs en 3D.Java a choisi d'imposer une récupération de place, alors que vous pouvez choisir en C ++. Vous pouvez vraiment creuser tout le chemin et vous rapprocher du matériel. Vous pouvez compresser les données de manière dense dans des structures. Vous pouvez effectuer de la magie noire, telle que la racine carrée inverse rapide . Vous pouvez effectuer certaines des métaprogrammations les plus complexes et les plus cryptées du monde à l'aide de modèles. Mais cela signifie également que vous pouvez vous perdre et passer des heures à déboguer tout le gâchis que vous avez créé ou à rechercher des erreurs absolument inutiles du compilateur.
Mais si vous avez la discipline d’utiliser uniquement les parties du langage que vous maîtrisez vraiment, vous pouvez écrire du code C ++ de manière aussi sûre que du code Java, mais vous avez la possibilité d’avancer progressivement.
Ainsi, bien que rien ne vous empêche techniquement d'écrire des logiciels de pointe avec Java, vous constaterez que de nombreux développeurs se passionnent pour écrire de bons logiciels, pour s'amuser et pour évoluer tout en allant au-delà de ce que Java peut offrir comme langage.
Mais le monde ne se compose pas seulement de personnes établies, mais crée la prochaine grande chose ou seulement de personnes qui restreindront l'utilisation du pouvoir qui leur est donné uniquement dans la mesure où elles le contrôlent. IMHO Java est la solution idéale pour les personnes qui souhaitent obtenir des résultats stables de manière confortable.
la source
La collecte des ordures est la grande chose. De temps en temps, GC verrouille tout le reste pendant plusieurs centaines de millisecondes (en fonction de la taille du segment) et effectue une collecte importante. C'est bien si vous n'avez aucune contrainte de temps, mais si être en retard signifie échec, c'est un spectacle. Vous pouvez dépenser de l'argent pour Java en temps réel et un système d'exploitation en temps réel, mais vous pouvez simplement utiliser GCC et Linux standard sans ces problèmes.
Sans les pauses aléatoires imprévisibles, Java est probablement assez rapide pour la plupart des choses de nos jours. Et si vous passez des mois à peaufiner vos paramètres GC, vous pouvez peut-être le faire fonctionner assez longtemps pour que le client vous fasse un chèque.
la source
3) Lacunes qui ont été corrigés.
Il y a quelques années, Java suscitait beaucoup de colère. La plupart des programmeurs Java sont des programmeurs Web / serveur et ils étaient fous de la verbosité de Java. Ainsi, certaines langues comme Ruby sont devenues populaires et Java a commencé à s'affaiblir. Cependant, avec les nouvelles annotations et les nouveaux frameworks tels que Hibernate et Spring, les utilisateurs ont cessé de se plaindre et sont revenus à Java.
4) Lacunes actuelles
Le matériel va tout multicœur. Bien que Java puisse faire du multithread, il est basé sur C qui est un langage séquentiel et la fonctionnalité pour le rendre multithread n’est pour le moins pas élégante. À propos, ce n’est pas seulement une critique de Java, mais presque toutes les langues. Une façon complètement différente de penser au code est nécessaire. Peut-être que la programmation fonctionnelle est la voie de l'avenir.
la source
J'ai en quelque sorte réagi à cette question parce qu'elle donnerait des réponses trompeuses et en grande partie non pertinentes:
Tout le monde peut convenir que les titres AAA seraient difficiles à produire avec Java et qu'il n'y a aucun exemple concret à ma connaissance. Cependant, étant donné la nature de AAA, cela suppose beaucoup de choses (puisqu'il s'agit en réalité d'un terme déroutant issu du marketing), il est donc préférable de poser la question suivante:
La réponse est " Oui, vous le pouvez ". Cependant, la partie réussie de l'équation est davantage basée sur votre persistance et votre chance (ou votre adhésion à Zeitgeist), mais cela dépasse le cadre de ce site.
la source
Une zone de vitesse certian se résume compilateur vs compilateur. Pas langue vs langue. La compilation JIT peut présenter des avantages, car elle peut être optimisée en fonction des spécifications de la machine sur laquelle elle est exécutée. Comparez JIT compilé C ++ vs Java pour une comparaison du compilateur plus "pomme à pomme".
Mais il y a certaines choses où le langage Java lui-même limite ses propres performances.
allocation sur la pile. Java ne peut pas faire ça. Ceci est souvent idéal pour les petites classes de taille fixe dans une solution non récursive. Vous pouvez également éviter la fragmentation du tas.
fonctions non virtuelles. Java ne peut pas faire ça. Tous les appels de méthode reçoivent un appel permanent même s’ils ne prévoient pas d’être annulés.
Probablement d'autres choses, mais c'est tout ce que je peux penser par cœur.
la source
1) non pertinent et argumentatif pour démarrer.
Non seulement de grands logiciels peuvent être créés en Java, mais de tels systèmes sont livrés chaque jour et gèrent désormais la plupart des grandes entreprises du monde.
2) idem.
Lisez les spécifications de la machine virtuelle Java et vous savez. Java n'a jamais été un langage interprété.
3) idem.
Lisez les notes de publication de 15 ans. Impossible pour nous de déterminer ce que vous considérez comme des "défauts majeurs" à résoudre.
4) idem.
Le principal problème à résoudre est le JCP, qui a tendance à se mêler du langage principal et des bibliothèques sans autre raison apparente que de faire figurer le nom de Somoene sur une JSR afin de pouvoir écrire un livre avec un texte de présentation autoritaire selon lequel chef de JSR-666 ". Espérons que la restructuration du JCP par Oracle s’occupe de cela.
Vous semblez simplement vouloir déclencher une guerre linguistique ici et faire confirmer vos préjugés à Java, car vous ne trouvez aucune justification réelle.
la source