35 votes

Est-il utile d'initialiser la taille de la collection d'une List<T> si sa taille est raisonnablement connue ?

Est-il utile d'initialiser la taille de la collection d'une List<T> si elle est raisonnablement connue ?

Edita: Après avoir lu les premières réponses, cette question se résume à la capacité par défaut et à la façon dont l'opération de croissance est effectuée, double-t-elle la capacité, etc.

68voto

Hans Passant Points 475940

Oui, ça devient important quand votre List<T> devient grand. Les chiffres exacts dépendent du type d'élément et de l'architecture de la machine. Prenons une liste de types de référence sur une machine 32 bits. Chaque élément prendra alors 4 octets dans un tableau interne. La liste commencera avec une capacité de 0 et un tableau vide. Le premier Add() fait passer la capacité à 4, en réallouant le tableau interne à 16 octets. Quatre Add() plus tard, le tableau est plein et doit être réaffecté à nouveau. Il double la taille, la capacité passe à 8, la taille du tableau à 32 octets. Le tableau précédent est un déchet.

Cela se répète autant que nécessaire, plusieurs copies du tableau interne deviendront des déchets.

Quelque chose de spécial se produit lorsque le tableau a atteint 65 536 octets (16 384 éléments). L'Add() suivant double à nouveau la taille à 131 072 octets. Il s'agit d'une allocation de mémoire qui dépasse le seuil des "gros objets" (85 000 octets). L'allocation n'est maintenant plus effectuée sur le tas de génération 0, elle est prise dans le tas des gros objets.

Les objets situés sur le LOH font l'objet d'un traitement particulier. Ils ne sont collectés que lors d'une collecte de génération 2. Et le tas n'est pas compacté, il faut trop de temps pour déplacer de si gros morceaux.

Cela se répète autant que nécessaire, plusieurs objets LOH deviendront des déchets. Ils peuvent occuper la mémoire pendant un certain temps, les collectes de génération 2 ne se produisent pas très souvent. Un autre problème est que ces gros blocs ont tendance à fragmenter l'espace d'adressage de la mémoire virtuelle.

Cela ne se répète pas indéfiniment, tôt ou tard, la classe List doit réallouer le tableau et celui-ci a tellement grandi qu'il n'y a plus un seul trou dans l'espace d'adressage de la mémoire virtuelle pour le contenir. Votre programme se heurtera à une exception OutOfMemoryException. Généralement bien avant que toute la mémoire virtuelle disponible ait été consommée.

Pour faire court, en fixant la capacité tôt, avant de commencer à remplir la liste, vous pouvez réserver ce grand tableau interne dès le départ. Vous n'aurez pas tous ces blocs maladroits libérés dans le tas de gros objets et éviterez la fragmentation. En fait, vous serez en mesure de stocker beaucoup plus d'objets dans la liste et votre programme fonctionnera plus facilement puisqu'il y aura moins de déchets. Ne le faites que si vous avez une bonne idée de la taille de la liste, utiliser une grande capacité que vous ne remplirez jamais est du gaspillage.

19voto

Asad Butt Points 8989

Elle l'est, selon la documentation

Si la taille de la collection peut être estimée, spécifier la capacité initiale initiale élimine le besoin d'effectuer d'effectuer un certain nombre d'opérations de redimensionnement opérations de redimensionnement lors de l'ajout d'éléments à la liste(T).

8voto

Jon Skeet Points 692016

Eh bien, cela vous empêchera de devoir copier de temps en temps les valeurs de la liste (qui seront des références si le type d'élément est un type de référence) au fur et à mesure que la liste grandit.

S'il s'agit d'une liste particulièrement importante et que vous avez une bonne idée de sa taille, cela ne fera pas de mal. Cependant, si l'estimation de la taille implique des calculs supplémentaires ou une quantité significative de code, je ne m'en préoccuperais pas à moins que vous ne trouviez que cela devient un problème - cela pourrait vous distraire de l'objectif principal du code, et le redimensionnement est peu susceptible de causer des problèmes de performance à moins qu'il s'agisse d'une très grande liste ou que vous le fassiez souvent.

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