J'apprends C #.
Si je crée d'abord une variable pour contenir une liste.
mylist = new List<int>();
Disons que j'ai travaillé avec la liste, maintenant je veux effacez la liste pour l'utiliser pour autre chose. donc je fais l'une des choses suivantes:
Méthode 1:
mylist.Clear();
Méthode 2:
List<int> mylist = new List<int>();
Le but est simplement de vider toutes les valeurs de la liste pour réutiliser la liste.
Y a-t-il un effet secondaire avec l'utilisation de method2. Dois-je favoriser une méthode à la suivante.
J'ai également trouvé une question similaire, Utilisation de la méthode "clear" par rapport au nouvel objet Je vais laisser les autres lecteurs décider de ce qui convient le mieux à leur propre cas d'utilisation. Je ne choisirai donc pas la bonne réponse.
3 Réponses :
Y a-t-il des effets secondaires avec l'utilisation de method2? Oui. Premièrement, il y a une allocation d'un nouvel objet, Deuxièmement, la première liste peut être collectée la prochaine fois que le garbage collector collecte.
Dois-je privilégier une méthode à la suivante.? Vous devriez privilégier la première méthode, car elle exprime votre intention, pour effacer la liste, plus clairement.
La méthode 2 provoquera une réallocation tandis que la méthode 1 efface simplement le tableau interne afin que le ramasse-miettes puisse récupérer la mémoire:
De la source:
// Clears the contents of List.
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++;
}
https://referencesource.microsoft.com/#mscorlib/system/collections /generic/list.cs,2765070d40f47b98
Je pense que la réallocation coûtera moins cher que d'effacer le tableau. Dans tous les cas, les performances sont probablement négligeables à moins que vous ne fassiez un travail vraiment super intensif. Dans ce cas, vous envisageriez probablement d'utiliser une structure de données plus rapide qu'une liste de toute façon.
tandis que la méthode 1 efface simplement le tableau interne afin que le ramasse-miettes puisse récupérer la mémoire faux la première méthode ne causera aucun travail GC edit: . .. pour List itsef - bien sûr si List stockera un autre objet que les primitives, il le ferait - mais encore une fois, pour List il n'y aura pas de travail GC
et à propos de Array.Clear c'est un appel très simple RtlSecureZeroMemory (* _ items, size * sizeof (T)) sur la plate-forme Windows (pour les primitives) ... quand "réallocation" est alloc + créer une nouvelle instance de List, alloc + créer tous les champs de la classe List ... et alloc dans .net n'est pas un simple appel RtlAllocateHeap ... vous devez créer un pointeur pour GC, etc. etc. (encore une fois pour List
L'utilisation de la méthode 2 peut entraîner un comportement inattendu au sein de votre programme selon la façon dont vous utilisez la liste.
Si vous deviez faire quelque chose comme:
List<int> myList = new List<int> { 1, 2, 3 };
someObj.listData = myList;
myList = new List<int>(); // clearing the list.
le les données dans "someObj" seront toujours 1,2,3.
Cependant, si vous utilisiez myList.clear () à la place, les données de "someObj" seraient également effacées.
Une pensée supplémentaire que je viens d'avoir. Si vous avez des références pendantes à la liste d'origine et que vous réaffectez la variable en utilisant new afin de l'effacer, le GC ne nettoiera jamais cette mémoire. Je dirais qu'il est toujours plus sûr d'utiliser la méthode .clear () si vous avez besoin de vider le contenu d'une liste.
Si vous faites
List mylist = new List (); , alors vous créez une nouvelle liste prête à l'emploi. Inutile de l'effacer, il est prêt à l'emploi, il suffit d'y accéder via votre variable (ma liste) qui contient une référence à celui-ci. Si vous réaffectez la liste (mylist = new List (); ), alors l'ancienne liste n'est plus référencée par votre code (s'il n'y a pas d'autres références à cette liste, alors elle est prête pour Garbage Collection ) et vous créez une nouvelle liste. Votre variablemylistcontient désormais une référence à cette nouvelle liste, et elle est prête à être utilisée de la même manière.L'effacement aidera à une allocation inutile et à une collecte de GC inutile, mais laissera plus de mémoire allouée ... donc la question est principalement basée sur l'opition: vitesse vs utilisation de la mémoire
Le seul autre facteur réel est l'existence d'autres références partagées à cette liste. Si vous la désactivez, ces références continuent à utiliser la liste partagée. En la renouvelant, cette partie du code abandonne l'ancienne liste et commence à en utiliser une nouvelle afin que les modifications apportées après ce point ne soient pas reflétées dans les autres références partagées.