Je vois que les réponses proposées se concentrent sur la performance. L'article fourni 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 l' System.Collections.Generic
espace de noms.
http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
Extraits:
Dictionnaire <>
Le dictionnaire est probablement la classe de conteneurs associatifs la plus utilisée. Le dictionnaire est la classe la plus rapide pour les recherches / insertions / suppressions associatives car il utilise une table de hachage sous les couvertures . Étant donné que les clés sont hachées, le type de clé doit correctement implémenter 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 / suppression / recherche des éléments dans le dictionnaire est amorti en temps constant - O (1) - ce qui signifie que quelle que soit la taille du dictionnaire, le temps nécessaire pour trouver quelque chose reste relativement constant. Ceci est hautement souhaitable pour les recherches à grande vitesse. Le seul, inconvénient est que le dictionnaire, de par la nature de l'utilisation d'une table de hachage, n'est pas ordonné, doncvous ne pouvez pas facilement parcourir les éléments d'un dictionnaire dans l'ordre .
SortedDictionary <>
Le SortedDictionary est similaire au Dictionary dans son utilisation mais très différent dans sa mise en œuvre. Le SortedDictionary utilise une arborescence binaire sous les couvertures pour maintenir les éléments dans l'ordre par 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 recherche pour la capacité de maintenir les éléments dans l'ordre, ainsi les temps d'insertion / suppression / recherche dans un dictionnaire trié sont logarithmiques - O (log n). De manière générale, avec le 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 souhaitez des recherches rapides, mais que vous souhaitez également pouvoir maintenir la collection dans l'ordre par la clé.
SortedList <>
La SortedList est l'autre classe de conteneurs associatifs triés dans les conteneurs génériques. Une fois de plus, 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 forme de tableau trié d'éléments. 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 de déplacer tous les éléments vers le haut ou vers le bas dans la liste. Cependant, le temps de recherche est O (log n) car la SortedList peut utiliser une recherche binaire pour trouver n'importe quel élément de la liste par sa clé. Alors, pourquoi voudriez-vous faire ça? Eh bien, la réponse est que si vous allez charger la SortedList à l'avance, les insertions seront plus lentes, mais comme l'indexation de tableau est plus rapide que de suivre des liens d'objet, les recherches sont légèrement plus rapides qu'un SortedDictionary. Encore une fois, j'utiliserais ceci dans les situations où vous voulez des recherches rapides et que vous souhaitez maintenir la collection dans l'ordre par la clé, et où les insertions et les suppressions sont rares.
Résumé provisoire des procédures sous-jacentes
Les commentaires sont les bienvenus car je suis sûr que je n'ai pas tout bien fait.
- 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
, trouve i
où HashArray(i) = Key.GetHash
# O (log n) (tableau trié)
- Supprimer
HashArray(i)
# O (n) (tableau trié)
- Supprimer
KeyArray(i)
# O (1)
- Supprimer
ItemArray(i)
# O (1)
Obtenir l'article
For i = 0 to n
, trouve i
où HashArray(i) = Key.GetHash
# O (log n) (tableau trié)
- Revenir
ItemArray(i)
Boucle à travers
For i = 0 to n
, revenir 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
, trouve i
où 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
où KeyArray(i).GetHash = Key.GetHash
# O (n)
- Supprimer
KeyArray(SortArray(i))
# O (n)
- Retirer
ItemArray(SortArray(i))
# O (n)
- Supprimer
OrderArray(i)
# O (n) (tableau trié)
Obtenir l'article
For i = 0 to n
, trouver i
où KeyArray(i).GetHash = Key.GetHash
# O (n)
- Revenir
ItemArray(i)
Boucle à travers
For i = 0 to n
, revenir ItemArray(OrderArray(i))
SortedList
Mémoire
KeyArray(n) = sorted array<pointer>
ItemArray(n) = sorted array<pointer>
Ajouter
For i = 0 to n
, trouve i
où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
où KeyArray(i).GetHash = Key.GetHash
# O (log n)
- Retirer
KeyArray(i)
# O (n)
- Supprimer
ItemArray(i)
# O (n)
Obtenir l'article
For i = 0 to n
, trouve i
oùKeyArray(i).GetHash = Key.GetHash
# O (log n)
- Revenir
ItemArray(i)
Boucle à travers
For i = 0 to n
, revenir ItemArray(i)