Parce qu'il y a une énorme différence entre optimiser les performances et désactiver complètement une sécurité
En réduisant le nombre de GC, leur structure est plus réactive et peut fonctionner (vraisemblablement) plus rapidement. Maintenant, l'optimisation pour le ramasse-miettes ne signifie pas qu'ils ne font jamais de ramasse-miettes. Cela signifie simplement qu'ils le font moins souvent, et quand ils le font, cela fonctionne très rapidement. Ce type d'optimisation comprend:
- Minimiser le nombre d'objets qui se déplacent vers un espace survivant (c'est-à-dire qui ont survécu à au moins une collecte des ordures) en utilisant de petits objets jetables. Les objets qui se sont déplacés vers l'espace du survivant sont plus difficiles à collecter et une collecte de déchets ici implique parfois de geler toute la JVM.
- N'allouez pas trop d'objets pour commencer. Cela peut se retourner si vous ne faites pas attention, car les objets de la jeune génération sont super bon marché à allouer et à collecter.
- Assurez-vous que le nouvel objet pointe vers l'ancien (et non l'inverse) afin que le jeune objet soit facile à collecter, car il n'y a aucune référence à ceux-ci qui entraînera sa conservation.
Lorsque vous désactivez les performances, vous ajustez généralement un "point chaud" très spécifique tout en ignorant le code qui ne s'exécute pas souvent. Si vous faites cela en Java, vous pouvez laisser le garbage collector s'occuper de ces coins sombres (car cela ne fera pas beaucoup de différence) tout en optimisant très soigneusement la zone qui s'exécute en boucle serrée. Vous pouvez donc choisir où vous optimisez et où vous ne le faites pas, et vous pouvez ainsi concentrer vos efforts là où cela compte.
Maintenant, si vous désactivez complètement la récupération de place, vous ne pouvez pas choisir. Vous devez vous débarrasser manuellement de chaque objet, jamais. Cette méthode est appelée au plus une fois par jour? En Java, vous pouvez le laisser faire, car son impact sur les performances est négligeable (il peut être correct de laisser un GC complet se produire chaque mois). En C ++, vous perdez toujours des ressources, vous devez donc prendre soin même de cette méthode obscure. Vous devez donc payer le prix de la gestion des ressources dans chaque partie de votre application, tandis qu'en Java, vous pouvez vous concentrer.
Mais ça empire.
Et si vous avez un bug, disons dans un coin sombre de votre application qui n'est accessible que le lundi à la pleine lune? Java a une forte garantie de sécurité. Il y a peu ou pas de "comportement indéfini". Si vous utilisez quelque chose de mal, une exception est levée, votre programme s'arrête et aucune corruption de données ne se produit. Vous êtes donc presque sûr que rien de mal ne peut se produire sans que vous vous en rendiez compte.
Mais dans quelque chose comme D, vous pouvez avoir un mauvais accès au pointeur, ou un débordement de tampon, et vous pouvez corrompre votre mémoire, mais votre programme ne le saura pas (vous avez désactivé la sécurité, rappelez-vous?) Et continuera à fonctionner avec son incorrect données, et faire des choses assez désagréables et corrompre vos données, et vous ne savez pas, et comme plus de corruption se produit, vos données deviennent de plus en plus erronées, puis soudainement elles se cassent, et c'était dans une application vitale, et une erreur est survenue dans le calcul d'une fusée, et il ne fonctionne pas, et la fusée explose, et mourir quelqu'un, et votre entreprise est dans la première page de tous les journaux et votre patron point de son doigt pour vous dire : « vous êtes l'ingénieur qui a suggéré que nous utilisions D pour optimiser les performances, comment se fait- il que vous n'ayez pas pensé à la sécurité?". Et c'est de ta faute. Tu as tué ces gens avec ta folle tentative de performance.
OK, ok, la plupart du temps c'est beaucoup moins dramatique que ça. Mais même une application critique pour l'entreprise ou simplement une application GPS ou, disons, un site Web gouvernemental de santé peut avoir des conséquences assez négatives si vous avez des bugs. Utiliser un langage qui les empêche complètement ou qui échoue lorsqu'ils surviennent est généralement une très bonne idée.
Il y a un coût à désactiver une sécurité. Devenir natif n'a pas toujours de sens. Parfois, il est beaucoup plus simple et plus sûr d'optimiser un peu un langage sûr pour aller dans une langue où vous pouvez vous tirer une balle dans le pied. L'exactitude et la sécurité dans de nombreux cas l'emportent sur les quelques nano secondes que vous auriez supprimées en éliminant complètement le GC. Disruptor peut être utilisé dans ces situations, donc je pense que LMAX-Exchange a fait le bon appel.
Mais qu'en est-il de D en particulier? Vous avez un GC si vous le souhaitez pour les coins sombres, et le sous-ensemble SafeD (que je ne connaissais pas avant l'édition) supprime le comportement indéfini (si vous vous souvenez de l'utiliser!).
Eh bien, dans ce cas, c'est une simple question de maturité. L'écosystème Java est plein d'outils bien écrits et de bibliothèques matures (mieux pour le développement). Beaucoup plus de développeurs connaissent Java que D (mieux pour la maintenance). Choisir une langue nouvelle et moins populaire pour quelque chose d'aussi critique qu'une application financière n'aurait pas été une bonne idée. Avec un langage moins connu, si vous avez un problème, peu de gens peuvent vous aider, et les bibliothèques que vous trouvez ont tendance à avoir plus de bugs car elles ont été exposées à moins de personnes.
Donc, mon dernier point tient toujours: si vous voulez éviter des problèmes aux conséquences désastreuses, restez avec des choix sûrs. A ce stade de la vie de D, ses clients sont les petites start-ups prêtes à prendre des risques fous. Si un problème peut coûter des millions, il vaut mieux rester plus loin dans la courbe en cloche de l' innovation .