J'utilisais SortedList () dans une classe qui stocke environ 15-100 000 données. P>
Récemment, mes exigences ont été modifiées, les données ne doivent plus être stockées comme triées, donc je suis passé à la liste (). P>
Cependant, dans ce cas, j'ai remarqué que la liste () consomme environ 20% + plus de mémoire. P>
Articles 9k: strong> p>
Articles 15K: strong> p>
Dans l'environnement que je développe, la mémoire est assez cruciale. Au lieu de la liste () Que puis-je utiliser pour éviter cette consommation de mémoire supplémentaire et avoir toujours une liste non triée? P>
p. J'utilise un hashset (de chaîne) pour fournir une vérification de l'unicité lors de l'utilisation de la liste (de) pour simuler la tritedlist.Containskey () bien que je ne pense pas que cela puisse apporter de telles tarifs de mémoire. Em> p>
p. 2: Mon application a environ 80 Mo d'allocation de mémoire de base dans le démarrage. Les chiffres doivent donc lire comme 105-80 = 25, 125-80 = 45 et ainsi de suite sur em> p>
Merci pour toutes les réponses, les résultats finaux sont les suivants: p>
Certains Bencmarks: strong>
500 caractères, 250000 insert p>
Liste (de chaîne) (50000) forte> p>
274 ms - 226 mb p>
triédlist (de chaîne, chaîne) (50000) strong> p>
34868 MS - 230 Mo P>
hashset fort> p>
420 ms - 232 Mo p>
486 ms - 234 MB p>
Bien que quand je l'ai changé le nombre a diminué à 25, puis: p>
hashset strong> pour 600.000 Itération 300 MB où En outre sur l'utilisation de la mémoire HashSet: http: //blog.mischel. com / 2008/04/09 / HashSet-limites / Dictionnaire (de ficelle, objet) n'a pas été beaucoup mieux soit dans mon test. p>
6 Réponses :
Si vous avez déjà un hashset de votre collection, je ne sais pas pourquoi vous avez également besoin d'une liste, mais si vous recherchez un conteneur qui garantit une fonctionnalité unicité et contenant (), pourquoi pas un dictionnaire générique? p>
Quelle que soit votre décision sur les questions ci-dessus, l'utilisation de quelque chose comme le gestionnaire de tâches est trop inexacte pour prendre des décisions sur la consommation de mémoire dans .NET. Si vous ne l'avez pas déjà fait, saisissez un essai de Profileur de mémoire .NET SCITECH ou Profiler et exécutez votre application. Prenez un instantané de votre utilisation de la mémoire avant de charger votre ensemble et juste après la comparaison. Vous pouvez le faire avec plusieurs types de collecte pour mesurer l'utilisation de la mémoire relative de chacune de manière très précise. p>
+1 pour recommander l'utilisation d'un profileur pour obtenir des données précises.
Prévenez-vous la liste Petite expérience que j'ai faite: p> Ce programme prend ~ 640MB p> Ce programme prend ~ 320 Mo P> Liste
List<int> list = new List<int>(100000000);
for (int i = 0; i < 100000000; i++)
{
list.Add(i);
}
+1 Il s'agit d'une excellente observation car une liste préélocalisée prendra un bloc de RAM contigu à la fois s'il le peut et réduira la surcharge générale générée par la fragmentation de la mémoire.
Très bon point, je vais essayer maintenant. Le même problème n'existe pas pour la tri ()?
Tous les conteneurs ayant la propriété «capacité» doivent être définis pour une performance optimale.
Ce que j'essaie de dire que cela devrait être non pertinent dans cette affaire de comparaison depuis que je comparais la liaison () et la liste () et ne l'a pas prélevé.
La liste
Je vous ferai savoir que la capacité de BTW fait une énorme différence, merci pour la pointe.
Apparemment, le problème se passait en fait à cause de Hashset () Il utilise une quantité énorme de mémoire. Maintenant, j'ai besoin de trouver un meilleur type de données pour stocker cette clé unique.
HASHSETS (& HASHTABLES) Utilisez beaucoup de mémoire! Beaucoup plus qu'une simple liste / type de tri p>
Un dictionnaire utilise deux fois plus de mémoire en interne comme une liste (50% plus sur un système 64 bits), la différence n'est donc pas si grande.
Eh bien, ce n'est pas exactement 50%. Les hashables ne sont jamais pleines à 100%, elles sont reformulées lorsqu'elles atteignent 70%. Les listes sont seulement redimensionnées lorsque elles sont complètement pleines.
A Clairement, le 72 Ko n'est même pas proche de la différence de 20 Mo que vous voyez, de sorte que l'utilisation de la mémoire de la liste elle-même ne peut pas être la cause. Compte tenu de savoir que la liste triée doit également conserver une référence à chaque objet, de sorte que l'utilisation de la mémoire devrait être identique. P>
Donc, soit il y a autre chose à l'aide de la mémoire, ou vous ne regardez pas l'utilisation de la mémoire réelle de l'application. Si vous recherchez dans le gestionnaire de tâches, vous ne voyez pas la quantité de mémoire utilisée, uniquement à quel point le gestionnaire de mémoire est attribué. P> Liste
Vérifiez les collections de puissance par Wintellect, l'équivalent .NET pour les collections de type STL. Je crois que le type de jeu devrait vous donner la fonctionnalité dont vous avez besoin (unicité), mais vous devez effectuer les repères à comparaison. Juste mes 2 cents. P>
Je recommanderais de regarder des listes vitrées ( http://sites.google.com/site/ Glazedlists / ). Celles-ci sont très rapides pour le tri et sont formidables avec la mémoire. P>
D'où avez-vous reçu ces valeurs?
À partir de mon application de test, bien que la mémoire puisse la mémoire de base de la mémoire - d'environ 80 Mo).
Du chef de la tâche (ou similaire)? Essayez d'utiliser un profileur (comme CLRProfiler: Microsoft. com / téléchargements / ... ). Les données de la mémoire du gestionnaire de tâches dépendent du comportement de la collecte des ordures.
Je m'attendrais à ce que l'empreinte de la liste de la liste () est à propos de "Tailleof (t)" * Capacité de la liste (pouvant être vérifiée). Si T est une classe, que vous ne stockez que des références, je m'attendrais donc, cette empreinte réelle de votre liste est minimale (15k articles * 4 octets), peut-être quelque chose d'autre qui a changé, cela a plus que les données elles-mêmes ?
Ignorer mon dernier commentaire si ces données sont venues d'un profileur ...
@Ravadre: En fait, étant donné que la liste est basée sur une matrice, il y a toujours des emplacements vides. Vous pouvez donc vous attendre à ce que quelque chose de 15k * (taille de référence) à 30k * (taille de référence).
@Martinho Ces chiffres sont cohérents et pas seulement des rapports d'une fois. Cela fonctionne pendant 5 minutes environ. Donc, je peux regarder régulièrement la croissance et comparer.
@Martinho: C'est pourquoi j'ai mentionné la capacité, non de longueur, car la capacité vous donne la quantité de telles machines à sous, qui sont attribuées par la liste et non le nombre d'éléments. Par conséquent, c'est toujours la capacité * 15k :)
@Ravadre c'est des références. SortedList () a également eu des clés de chaîne. Mais la liste () utilise hashset () pour stocker les mêmes clés de chaîne.
@Ravadre Data est exactement la même chose, je viens de changer mon héritage de classe de la sélection () à la liste () et la mémoire augmente.
@dr. Evil - et que se passe-t-il si vous lancez un jeu de hasch Uut, il suffit de garder la liste? La liste est en fait un tableau sous le capot (comme dit Martinho), donc même si vous allouez de l'espace pour des éléments 300K, il reste environ 1,2 Mo uniquement (2,4 Mo sur 64 bits), la liste elle-même ne peut pas consommer beaucoup de mémoire. Les données ou autres structures, comme les ensembles de hachages doivent
Je peux supprimer le hashset mais n'a pas d'importance car au lieu de hashset, la même chaîne sera stockée en tant que clé de liste triée. Donc, wather wat ce sont les mêmes données stockées.