Capacité initiale de types de collection, par exemple, le Dictionnaire, la Liste
Certains types de collection dans .Net disposer en option d'une "Capacité Initiale" paramètre du constructeur. Par exemple:
Dictionary<string, string> something = new Dictionary<string,string>(20);
List<string> anything = new List<string>(50);
Je n'arrive pas à trouver ce que le défaut initial de la capacité d'accueil est de ces objets sur le site MSDN.
Si je sais que je vais seulement le stockage de 12 ou alors des éléments dans un dictionnaire, n'est-il pas logique de définir la capacité initiale de quelque chose comme 20?
Mon raisonnement est, en supposant que la capacité se développe comme il le fait pour un StringBuilder, qui double chaque fois que la capacité est touché, et chaque réaffectation est coûteux, pourquoi ne pas pré-régler la taille de quelque chose que vous savez dans votre prise de données, avec certains chambre supplémentaire juste au cas où? Si la capacité initiale est de 100, et je sais que je vais seulement besoin d'une douzaine ou alors, il semble comme si le reste de la mémoire est allouée pour rien.
Vous devez vous connecter pour publier un commentaire.
Si les valeurs par défaut ne sont pas documentés, la raison en est probablement la meilleure capacité initiale est de un détail de l'implémentation et sous réserve de changements entre les versions framework. Qui est, vous ne devriez pas écrire le code qui suppose une certaine valeur par défaut.
Le constructeur surcharges avec une capacité pour les cas dans lesquels vous savez mieux que la classe de ce nombre d'éléments sont à prévoir. Par exemple, si vous créez une collection de 50 valeurs et le savoir que ce nombre n'augmente jamais, vous pouvez initialiser la collection avec une capacité de 50, afin de ne pas avoir à redimensionner si la valeur par défaut de la capacité est plus faible.
Cela dit, vous pouvez déterminer les valeurs par défaut à l'aide de Réflecteur. Par exemple, dans .NET 4.0 (et probablement les versions précédentes ainsi),
une Liste<T> est initialisé avec une capacité de 0. Lorsque le premier élément est ajouté, il est réinitialisé à une capacité de 4. Par la suite, chaque fois que la capacité est atteinte, la capacité est doublée.
un Dictionnaire<T> est initialisée avec une capacité de 0 ainsi. Mais il utilise un complètement différent de l'algorithme d'augmentation de la capacité: il augmente la capacité de toujours des nombres premiers.
La vérification de la source, la valeur par défaut pour les deux
List<T>
etDictionary<TKey, TValue>
est de 0.Si vous connaissez la taille, puis le dire; un mineur d'optimisation dans la plupart des "petits" des cas, mais utile pour les grandes collections. Je principalement vous inquiéter à ce sujet si je jette un "décent" quantité de données, comme il peut, puis éviter d'avoir à allouer, de copie et de collecter de multiples tableaux.
La plupart des collections, en effet, utiliser une stratégie de doublement.
Un autre problème avec l'ConcurrentDictionary (actuellement) et à l'aide de son constructeur pour définir une taille initiale, c'est que sa performance semble être entravée.
Par exemple, voici un exemple de code et de repères j'ai essayé.
J'ai couru le code sur ma machine et a obtenu des résultats similaires.
Lorsque la taille initiale est spécifié, il ne fait rien pour augmenter la ConcurrentDictionary de la vitesse lors de l'ajout d'objets. Techniquement, je pense qu'il devrait parce qu'il n'a pas à prendre de temps ou de ressources pour redimensionner lui-même.
Oui, il ne peut pas courir aussi vite que normal d'un Dictionnaire, mais je serais encore attendre un ConcurrentDictionary avec sa taille initiale définie à la cohérence, des performances plus rapides qu'un ConcurrentDictionary qui ne possède pas sa taille initiale, surtout lorsque l'on sait à l'avance le nombre d'éléments qui vont être ajoutés.
Donc la morale de l'histoire est le réglage de la taille initiale ne garantit pas toujours une amélioration de la performance.