Je vois que les réponses proposées se concentrent sur la performance. L'article ci-dessous n'apporte rien de nouveau concernant les performances, mais il explique les mécanismes sous-jacents. Notez également qu'il ne se concentre pas sur les trois Collection
types mentionnés dans la question, mais aborde tous les types de la System.Collections.Generic
espace de noms.
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
Des extraits :
Dictionnaire<>
Le dictionnaire est probablement la classe de conteneur associative la plus utilisée. Le dictionnaire est la classe la plus rapide pour les recherches/insertions/suppressions associatives parce que il utilise une table de hachage sous les couvertures . Parce que les clés sont hachées, le type de clé doit implémenter correctement GetHashCode() et Equals() de manière appropriée ou vous devez fournir un IEqualityComparer externe au dictionnaire lors de la construction. Le temps d'insertion, de suppression et de consultation des éléments du dictionnaire est un temps constant amorti - O(1) - ce qui signifie que quelle que soit la taille du dictionnaire, le temps nécessaire pour trouver quelque chose reste relativement constant. C'est très souhaitable pour les recherches rapides. Le seul inconvénient est que le dictionnaire, de par la nature de l'utilisation d'une table de hachage, est non ordonné, donc vous ne pouvez pas facilement parcourir les éléments d'un dictionnaire pour .
SortedDictionary<>
Le SortedDictionary est similaire au Dictionary dans son utilisation mais très différent dans son implémentation. Le site SortedDictionary utilise un arbre binaire sous les couvertures pour maintenir les éléments dans l'ordre de la clé. . En conséquence du tri, le type utilisé pour la clé doit implémenter correctement IComparable afin que les clés puissent être correctement triées. Le dictionnaire trié échange un peu de temps de consultation contre la possibilité de maintenir les éléments dans l'ordre, ainsi les temps d'insertion/suppression/ consultation dans un dictionnaire trié sont logarithmiques - O(log n). En général, avec un temps logarithmique, vous pouvez doubler la taille de la collection et il suffit d'effectuer une comparaison supplémentaire pour trouver l'élément. Utilisez le SortedDictionary lorsque vous voulez des recherches rapides mais que vous souhaitez également pouvoir maintenir la collection dans l'ordre de la clé.
Liste triée<>
La SortedList est l'autre classe de conteneurs associatifs triés dans les conteneurs génériques. Encore une fois, SortedList, comme SortedDictionary, utilise une clé pour trier les paires clé-valeur . Contrairement à SortedDictionary, cependant, Les éléments d'une SortedList sont stockés sous la forme d'un tableau d'éléments triés. . Cela signifie que les insertions et les suppressions sont linéaires - O(n) - car la suppression ou l'ajout d'un élément peut impliquer le déplacement de tous les éléments vers le haut ou le bas de la liste. Le temps de recherche, cependant, est O(log n) parce que la SortedList peut utiliser une recherche binaire pour trouver n'importe quel élément de la liste par sa clé. Alors pourquoi vouloir faire cela ? Eh bien, la réponse est que si vous chargez la SortedList à l'avance, les insertions seront plus lentes, mais comme l'indexation des tableaux est plus rapide que le suivi des liens entre objets, les recherches sont légèrement plus rapides qu'avec un SortedDictionary. Une fois de plus, je l'utiliserais dans des situations où vous voulez des recherches rapides et où vous voulez maintenir la collection dans l'ordre de la clé, et où les insertions et les suppressions sont rares.
Résumé provisoire des procédures sous-jacentes
Tout commentaire est le bienvenu, car je suis sûr que je n'ai pas tout compris.
- Tous les tableaux sont de taille
n
.
- Tableau non trié = .Add/.Remove est O(1), mais .Item(i) est O(n).
- Tableau trié = .Add/.Remove est O(n), mais .Item(i) est O(log n).
Dictionnaire
Mémoire
KeyArray(n) -> non-sorted array<pointer>
ItemArray(n) -> non-sorted array<pointer>
HashArray(n) -> sorted array<hashvalue>
Ajouter
- Ajouter
HashArray(n) = Key.GetHash
# O(1)
- Ajouter
KeyArray(n) = PointerToKey
# O(1)
- Ajouter
ItemArray(n) = PointerToItem
# O(1)
Retirer
-
For i = 0 to n
, trouver i
donde HashArray(i) = Key.GetHash
# O(log n) (tableau trié)
- Retirer
HashArray(i)
# O(n) (tableau trié)
- Retirer
KeyArray(i)
# O(1)
- Retirer
ItemArray(i)
# O(1)
Obtenir un article
-
For i = 0 to n
, trouver i
donde HashArray(i) = Key.GetHash
# O(log n) (tableau trié)
- Retourner à
ItemArray(i)
Boucle à travers
-
For i = 0 to n
, retour ItemArray(i)
SortedDictionary
Mémoire
KeyArray(n) = non-sorted array<pointer>
ItemArray(n) = non-sorted array<pointer>
OrderArray(n) = sorted array<pointer>
Ajouter
- Ajouter
KeyArray(n) = PointerToKey
# O(1)
- Ajouter
ItemArray(n) = PointerToItem
# O(1)
-
For i = 0 to n
, trouver i
donde KeyArray(i-1) < Key < KeyArray(i)
(en utilisant ICompare
) # O(n)
- Ajouter
OrderArray(i) = n
# O(n) (tableau trié)
Retirer
-
For i = 0 to n
, trouver i
donde KeyArray(i).GetHash = Key.GetHash
# O(n)
- Retirer
KeyArray(SortArray(i))
# O(n)
- Retirer
ItemArray(SortArray(i))
# O(n)
- Retirer
OrderArray(i)
# O(n) (tableau trié)
Obtenir un article
-
For i = 0 to n
, trouver i
donde KeyArray(i).GetHash = Key.GetHash
# O(n)
- Retourner à
ItemArray(i)
Boucle à travers
-
For i = 0 to n
, retour ItemArray(OrderArray(i))
Liste triée
Mémoire
KeyArray(n) = sorted array<pointer>
ItemArray(n) = sorted array<pointer>
Ajouter
-
For i = 0 to n
, trouver i
donde KeyArray(i-1) < Key < KeyArray(i)
(en utilisant ICompare
) # O(log n)
- Ajouter
KeyArray(i) = PointerToKey
# O(n)
- Ajouter
ItemArray(i) = PointerToItem
# O(n)
Retirer
-
For i = 0 to n
, trouver i
donde KeyArray(i).GetHash = Key.GetHash
# O(log n)
- Retirer
KeyArray(i)
# O(n)
- Retirer
ItemArray(i)
# O(n)
Obtenir un article
-
For i = 0 to n
, trouver i
donde KeyArray(i).GetHash = Key.GetHash
# O(log n)
- Retourner à
ItemArray(i)
Boucle à travers
-
For i = 0 to n
, retour ItemArray(i)
0 votes
Ver stackoverflow.com/questions/935621/