70 votes

Ne pas mettre en rayon ou pas -

J'ai récemment vu deux conférences sur les langages vraiment intéressantes et instructives :

La première par Herb Sutter, présente toutes les fonctionnalités intéressantes et cool de C++0x, pourquoi l'avenir de C++ semble plus brillant que jamais, et comment M$ est dit être un bon joueur dans ce jeu. La conversation tourne autour de l'efficacité et comment minimiser l'activité sur le tas améliore très souvent les performances.

L'autre, par Andrei Alexandrescu, motive une transition de C/C++ vers son nouveau changement de jeu D. La plupart des choses de D semblent vraiment bien motivées et conçues. Une chose, cependant, m'a surpris, à savoir que D pousse pour la collecte des ordures et que toutes les classes sont créées uniquement par référence. Encore plus déroutant, le livre The D Programming Language Ref Manuel spécifiquement dans la section sur Resource Management déclare ce qui suit, citation:

La collecte des ordures élimine le code fastidieux et sujet aux erreurs de suivi de l'allocation de mémoire nécessaire en C et C++. Cela signifie non seulement un temps de développement beaucoup plus rapide et des coûts de maintenance plus bas, mais le programme résultant fonctionne fréquemment plus rapidement!

Cela entre en conflit avec le discours constant de Sutter sur la minimisation de l'activité sur le tas. Je respecte vivement les idées de Sutter et d'Alexandrescou, donc je me sens un peu confus concernant ces deux questions clés

  1. Le fait de créer des instances de classe uniquement par référence ne se traduit-il pas par beaucoup d'activité inutile sur le tas?

  2. Dans quels cas pouvons-nous utiliser la collecte des ordures sans sacrifier les performances en temps d'exécution?

45voto

dsimcha Points 32831

Pour répondre directement à vos deux questions:

  1. Oui, la création d'instances de classe par référence entraîne beaucoup d'activité de la heap, mais:

    a. En D, vous avez des struct ainsi que des class. Un struct a des sémantiques de valeur et peut faire tout ce qu'une classe peut, sauf la polymorphie.

    b. La polymorphie et les sémantiques de valeur n'ont jamais bien fonctionné ensemble en raison du problème de slicing.

    c. En D, si vous avez vraiment besoin d'allouer une instance de classe sur la stack dans un code critique en termes de performances et que vous ne vous souciez pas de la perte de sécurité, vous pouvez le faire sans trop de tracas via la fonction scoped.

  2. Le GC peut être comparable ou plus rapide que la gestion manuelle de la mémoire si:

    a. Vous allouez toujours sur la stack lorsque possible (comme vous le faites généralement en D) au lieu de tout baser sur la heap (comme c'est souvent le cas dans d'autres langages avec GC).

    b. Vous avez un garbage collector de pointe (l'implémentation actuelle du GC de D est avouons-le quelque peu naïve, bien qu'il ait bénéficié de quelques optimisations majeures lors des dernières versions, donc ce n'est pas aussi mauvais qu'avant).

    c. Vous allouez principalement de petits objets. Si vous allouez principalement de grands tableaux et que les performances deviennent un problème, vous voudrez peut-être en switcher quelques-uns vers le tas en C (vous avez accès à malloc et free de C en D) ou, s'ils ont une durée de vie délimitée, à un autre allocateur comme RegionAllocator. (RegionAllocator est actuellement en discussion et en amélioration en vue d'une inclusion éventuelle dans la bibliothèque standard de D).

    d. Vous ne vous souciez pas vraiment de l'efficacité de l'espace. Si vous faites tourner le GC trop fréquemment pour maintenir une empreinte mémoire ultra-faible, les performances en souffriront.

22voto

Jack Edmonds Points 10264

La raison pour laquelle la création d'un objet sur le tas est plus lente que sa création sur la pile est que les méthodes d'allocation de mémoire doivent gérer des choses comme la fragmentation du tas. Allouer de la mémoire sur la pile est aussi simple que d'incrémenter le pointeur de pile (une opération en temps constant).

Cependant, avec un collecteur de déchets compactant, vous n'avez pas à vous soucier de la fragmentation du tas, les allocations sur le tas peuvent être aussi rapides que les allocations sur la pile. La page Collecte des déchets pour le langage de programmation D explique cela plus en détail.

L'affirmation selon laquelle les langages avec GC s'exécutent plus rapidement suppose probablement que de nombreux programmes allouent de la mémoire sur le tas beaucoup plus souvent que sur la pile. En supposant que l'allocation sur le tas puisse être plus rapide dans un langage avec GC, il en découle que vous avez simplement optimisé une grande partie de la plupart des programmes (allocation sur le tas).

13voto

xtofl Points 22333

Une réponse à 1) :

Tant que votre tas est contigu, allouer dessus est aussi bon marché qu'allouer sur la pile.

De plus, lorsque vous allouez des objets qui se trouvent les uns à côté des autres, les performances de votre mise en cache de mémoire seront excellentes.

Tant que vous n'avez pas à exécuter le ramasse-miettes, aucune performance n'est perdue, et le tas reste contigu.

C'est la bonne nouvelle :)

Réponse à 2) :

La technologie GC a beaucoup progressé ; elle est même disponible aujourd'hui en temps réel. Cela signifie que garantir une mémoire contiguë est une question liée à la politique et dépendante de l'implémentation.

Donc si

  • vous pouvez vous permettre un gc en temps réel
  • il y a assez de pauses d'allocation dans votre application
  • il peut conserver votre liste libre en tant que bloc libre

Vous pourriez obtenir de meilleures performances.

Réponse à une question non posée :

Si les développeurs sont libérés des problèmes de gestion de mémoire, ils pourraient avoir plus de temps pour se concentrer sur les aspects de performance et de scalabilité réels de leur code. C'est un facteur non technique qui entre également en jeu.

4voto

Kate Gregory Points 13451

Ce n'est ni la "collecte des ordures" ni le code manuscrit "propice aux erreurs fastidieux". Des pointeurs intelligents vraiment intelligents peuvent vous donner une sémantique de pile et signifier que vous ne tapez jamais "delete" mais vous ne payez pas pour la collecte des ordures. Voici une autre vidéo par Herb qui souligne ce point - sûr et rapide - c'est ce que nous voulons.

4voto

BCS Points 18500

Un autre point à considérer est la règle des 80:20. Il est probable que la grande majorité des endroits que vous allouez sont sans rapport et que vous ne gagnerez pas grand-chose avec un GC même si vous pouviez réduire le coût à zéro. Si vous acceptez cela, alors la simplicité que vous pouvez gagner en utilisant un GC peut compenser le coût de son utilisation. C'est particulièrement vrai si vous pouvez éviter de faire des copies. Ce que D fournit est un GC pour les cas 80% et un accès à l'allocation sur la pile et au malloc pour les 20% restants.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X