Choisissez C ++ ou Java pour les applications nécessitant d'énormes quantités de RAM? [fermé]

11

Je pense aux applications scientifiques qui sont pour la plupart liées au processeur et qui utilisent beaucoup de tas (au moins plusieurs gigaoctets). À tout autre moment de l'année, j'irais volontiers avec C ++, mais dans ce cas, je me demande si la fragmentation naturelle du gestionnaire de mémoire C ++ peut être un problème sérieux par rapport à l'avantage des collecteurs de compactage Java.

Quelqu'un peut-il citer des exemples concrets liés à cela?

dsign
la source
Je ne pense pas que le langage soit aussi important que la programmation dans ce cas. Tout langage mature pourrait probablement fonctionner en fonction de l'échelle de votre calcul. Il existe des Javas, C / C ++, même des Pythons et des Rubis qui peuvent glisser dans ce rôle. Certains seraient plus difficiles que d'autres, car il semble que vous ayez vraiment besoin d'avoir l'assurance que vous ne perdez pas de mémoire.
Rig
2
Si vous pouvez obtenir un Go pour 7,99 $, est-ce un problème? Kingston 1GB DDR3
Bo Persson
2
@BoPersson, d'après mon expérience, les gens ayant ce genre de problèmes commencent par remplir complètement leur carte mère haut de gamme et se plaignent qu'ils ne peuvent pas y mettre autant qu'ils le souhaitent, puis alimentent un ensemble de données aussi gros que gérable et se plaignent ensuite que ce n'est pas suffisant.
Programmeur le
@dsign, en ces jours où la carte mère accepte plusieurs centaines de gigaoctets de mémoire pour moins de 1000 €, quelques gig ne sont pas très gourmands en mémoire.
Programmeur le
1
D'accord avec la partie mémoire bon marché. En ce qui concerne le développement, je suis en C ++ depuis un certain temps et les bonnes pratiques de codage font des fuites un phénomène assez rare; en fait, je préfère vraiment C ++ à java à cet égard.
dsign

Réponses:

11

Si vous parlez d'une application qui va forcément souligner les limites de la machine, de sorte que vous vous attendez à ce que vous fassiez des astuces de programmation pour éviter de dépasser ces limites, alors C ++ est la voie à suivre. Non seulement C ++ vous offre une marge d'optimisation là où Java ne le fait pas (comme l'a souligné Emilio), mais aussi, les Garbage-Collectors sont des engins très gourmands en mémoire qui ont besoin de beaucoup de mémoire libre supplémentaire pour fonctionner efficacement.

Les réponses à cette question: StackOverflow: combien de mémoire supplémentaire le nettoyage de la mémoire requiert-il ? peindre une image plutôt sombre, mais même si les ramasseurs de déchets ont besoin que la mémoire libre soit à peu près autant que la mémoire allouée, (ce que j'avais entendu), cela signifie toujours qu'avec Java, vous aurez toujours besoin de beaucoup de mémoire libre pour qu'il fonctionne efficacement.

D'un autre côté, de nos jours, nous préférons généralement acheter du matériel plus cher plutôt que d'avoir à effectuer des astuces de programmation pour éviter de dépasser les limites du matériel. Dans votre cas, vos problèmes de RAM seraient généralement résolus en utilisant une machine 64 bits et en y jetant autant de modules de RAM que nécessaire. Vous voyez, le coût du matériel est loin d'être le coût du temps de développement dans le monde développé de nos jours.

Je pense que vous devriez sérieusement envisager cette option, et si possible, aller avec cette option et avec Java au lieu de C ++, car il est beaucoup plus facile de développer quelque chose en Java qu'en C ++, et de continuer à le maintenir par la suite.

Mike Nakis
la source
Merci pour votre réponse. Je suis d'accord avec votre illustration matérielle.
dsign
Si vous ne vous souciez pas de la pause du programme pendant l'exécution de la récupération de place, les besoins en mémoire sont beaucoup plus petits.
1
Je ne suis pas d'accord avec le dernier paragraphe. Java n'est pas nécessairement plus facile à développer qu'en C ++. Ce ne serait pas pour moi, car j'ai fait beaucoup de C ++ et relativement peu de Java au cours des cinq ou six dernières années. Il est possible d'écrire du code maintenable et non maintenable à la fois en C ++ et Java.
David Thornley
1
@DavidThornley J'ai fait du C / C ++ pendant plus de 10 ans et Java depuis plus de 6 ans. Je trouve que Java est plus facile à tous points de vue: prototypage, développement, extension et maintenance. Mais en tout cas, c'est ce que les opinions sont censées faire: différer . C -: =
Mike Nakis
Avez-vous programmé pour un projet gourmand en données volumineuses? Y a-t-il des commentaires?
dsign
7

Le problème n'est pas d'utiliser C ++ car c'est Java et pas d'utiliser Java comme c'est C ++. Un conteneur C ++ est normalement implémenté pour éviter un excès de fragmentation, tout comme le font le magasin gratuit Java.

Mais si vous vous allouez directement la mémoire, vous pouvez également faire des choses que Java ne vous permet pas de faire, ce qui peut entraîner une fragmentation.

La bonne solution (en C ++) est d'utiliser des conteneurs et des pointeurs intelligents via des classes d'allocateurs qui gèrent l'allocation au moyen de "plex" fixes (le point clé, ici, est d'écrire une bonne classe d'allocateurs). Et c'est un style de programmation qui n'a rien à voir avec Java, donc toute comparaison n'a aucun sens.

[MODIFIER] Il peut s'agir d'un exemple obsolète: allocation fixe

Emilio Garavaglia
la source
Merci pour ta réponse Emilio. Je connais bien la flexibilité de C ++ et je suis enclin à être d'accord avec vous. Là encore, je voudrais connaître quelques exemples d'utilisation réels où ces techniques ont été utilisées avec succès.
dsign
@dsign: Post édité, voir le lien
Emilio Garavaglia
1
J'ai utilisé ces techniques auparavant. Une application peu performante a vu son allocateur modifié pour utiliser un ensemble de segments de blocs fixes. Donc, quand vous vouliez un bloc de 4 octets, il venait du tas qui ne stockait que des blocs de 4 octets. Si vous vouliez 5 octets, cela provenait du tas de blocs de 8 octets, etc. L'augmentation des performances (pour notre application fortement allouée) était énorme. Vous n'obtiendrez peut-être pas un aussi bon résultat, mais cela peut être très efficace. Il n'y avait également aucune fragmentation, car toutes les allocations étaient fournies en blocs fixes.
gbjbaanb
2

L'avantage du garbage collection est qu'il simule une machine avec une quantité infinie de mémoire. Le mécanisme ou l'implémentation de cette abstraction est destiné à être complètement transparent pour vous en tant que programmeur. Nous savons tous que le mécanisme récupère de la mémoire qui n'est plus utilisée par le programme, mais ce n'est pas réellement garanti. Si vous exécutez le programme sur une machine avec plus de RAM que le programme n'en utilise jamais, le garbage collection peut ne jamais se produire. Encore une fois, non pertinent, car vous pouvez simplement écrire le programme sans égard à la façon dont il utilise la mémoire. Le gestionnaire de mémoire allouera simplement plus de RAM chaque fois que le programme le demandera, et vous pouvez supposer que de telles allocations réussiront toujours. Java est un langage récupéré, et C ++ ne l'est pas. 1

L'inconvénient de la récupération de place est que, comme toutes les abstractions , elle a tendance à fuir. Cela ne fonctionne pas toujours parfaitement tout le temps, en particulier dans les cas marginaux, et vous risquez de rencontrer des bugs. Les personnes qui ont écrit l'algorithme de récupération de place (celui qui est censé être transparent pour vous en tant que programmeur) optimisé pour les cas les plus courants, et le problème avec les cas courants, c'est qu'ils ne sont jamais si communs. En général , vous ne pouvez pas faire mieux que le garbage collector pour gérer la mémoire. Mais dans des circonstances spécifiques (et avec suffisamment de temps, d'énergie et de compréhension), cela pourrait être possible. C ++ vous donne cette flexibilité; Java ne le fait pas.

Cela dit, je pense que le conseil standard pour le choix d'une langue s'applique ici, peut-être encore plus dans ce cas, compte tenu des contraintes. Choisissez la langue la plus familière aux développeurs principaux du projet. En plus des raisons évidentes (comme vous pourrez développer l'application plus rapidement et plus efficacement), c'est particulièrementimportant dans le cas que vous décrivez parce que la programmation C ++ comme vous programmez Java va entraîner des pratiques de gestion de la mémoire terriblement inefficaces, et donc des fuites et des plantages. De façon similaire, la programmation en Java comme vous le faites en C ++ ne vous fera pas grand bien, et pourrait finir par produire un programme moins qu'optimisé, étant donné que les algorithmes de récupération de place sont ajustés et ajustés pour les cas les plus courants .

Les programmeurs habitués à travailler dans des langages récupérés apprennent à faire confiance au garbage collector, plutôt que de lutter contre lui. Si vous travaillez dans un langage récupéré, ce sont les programmeurs que vous souhaitez sur votre projet. Programmeurs qui ne sont pashabitués à travailler dans un langage récupéré sont intrinsèquement sceptiques à l'égard d'une telle abstraction de "mémoire infinie", et souvent avec de nombreuses bonnes raisons. Aussi bons que ces programmeurs puissent être, ce ne sont pas ceux que vous souhaitez travailler dans un langage récupéré car ils se battront contre le GC à chaque étape du processus, le devineront constamment et produiront souvent plus lentement, moins économes en mémoire code que l'autre type de programmeur. Au mieux, ils passeront juste beaucoup de temps à réinventer la roue, vous coûteront beaucoup d'argent et encore plus en coûts de maintenance à long terme.

Et puis vous devez également vous demander si cela compte vraiment. Il y a plus qu'un soupçon de vérité dans le commentaire sarcastique de Bo: la mémoire est si bon marché maintenant, elle ne vaut guère trop de se tordre la main. Même si vous avez besoin de montants massifs , ces montants ne sont plus aussi massifs maintenant qu'ils l'étaient il y a 10 ans. Les programmeurs et le développement d'applications coûtent beaucoup plus cher que l'achat de quantités de RAM et de puissance de traitement. Cela ne signifie pas que vous devez éviter l'économie dans la mesure du possible, mais cela signifie également que vous ne devriez pas perdre trop de temps à le faire.


1 Bien entendu, cette hypothèse met en évidence une faille plus profonde dans la question. Il s'avère que "Java ou C ++" est un peu un hareng rouge. L'implémentation Java standard fournit le ramasse-miettes et C ++ ne le fait pas selon la norme de langage, mais il n'y a absolument aucune raison que vous ne puissiez pas utiliser un ramasse-miettes tiers pour C ++. Beaucoup d'entreprises ont gagné leur vie en vendant ces choses, et certaines ont probablement gagné leur vie en les donnant gratuitement.

Cody Grey
la source