23 votes

Liste<T> À Rétrécir Si Vous Supprimez Des Éléments

Lorsqu'un List<T> est plein, il double de taille, occupant deux fois plus de mémoire, mais ne serait-il automatiquement la diminution de la taille si vous avez supprimé des éléments?

Autant je comprends la diminution de l' Capacity ne signifie pas la relocalisation de toutes les données en mémoire, il suffit de déposer la fin de la mémoire réservée, mais est-il vraiment le faire?

28voto

Servy Points 93720

Non, List ne jamais diminuer la capacité, sauf si vous explicitement bas vous-même en définissant la propriété ou à l'aide de TrimExcess, sauf lorsque vous appelez Clear et il peut enlever le tampon entièrement.

Bien sûr, c'est juste de la mise en œuvre actuelle, et c'est un détail d'implémentation, de sorte que vous ne pouvez pas compter sur elle de ne pas réduire la sauvegarde de tableau.

8voto

Joel Coehoorn Points 190579

Non, List<T> sera pas automatiquement récupérer tout l'espace tel qu'il est actuellement mis en œuvre, et il est peu probable que cette mise en œuvre va changer bientôt.

Mais c'est seulement une partie de l'histoire. Rappelez-vous que, d'une manière générale, List<T> stocke uniquement les références de vos articles. Si vous avez une grande liste avec de nombreux objets, et de vous retirer de la moitié d'entre eux est telle que rien ne utilise les objets déplacés plus, quelque chose de très près à la moitié de la mémoire-vous attribuer à votre liste va être récupérée lors de la GC recueille ces objets.

En outre, ma compréhension est la mise en œuvre actuelle sera compact le reste des éléments, tels que la liste s'accroît de nouveau, c'est de ré-utiliser des spots de mémoire allouée pour l'ensemble actuel utilisé par la liste en interne.

Enfin, il existe des moyens manuellement récupérer l'espace... mais les utiliser avec parcimonie. La plupart du temps, le GC sait mieux. Appelant TrimExcess() parce que vous venez de retirer une poignée d'articles d'une grande liste est généralement d'une perte nette de votre application.

8voto

Sweeper Points 1267

À partir de la source de référence, nous pouvons voir que l' Remove des appels à la méthode de l' RemoveAt méthode, qui est mis en œuvre comme ceci:

public void RemoveAt(int index) {
    if ((uint)index >= (uint)_size) {
        ThrowHelper.ThrowArgumentOutOfRangeException();
    }
    Contract.EndContractBlock();
    _size--;
    if (index < _size) {
        Array.Copy(_items, index + 1, _items, index, _size - index);
    }
    _items[_size] = default(T);
    _version++;
}

Il ne semble pas être tout le redimensionnement de la sous-matrice _items. Il définit uniquement l'élément à l'index de la valeur par défaut.

En gros, pas de.

Notez également que l' Clear méthode ne permet pas de redimensionner le tableau. Il appelle Array.Clear pour définir tous les éléments sous-jacents, au tableau, les valeurs par défaut.

public void Clear() {
    if (_size > 0)
    {
        Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
        _size = 0;
    }
    _version++;
}

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