J'essaie de comprendre quand et pourquoi utiliser un dictionnaire ou une table de hachage. J'ai fait une petite recherche ici et j'ai trouvé des gens qui parlaient des avantages génériques du dictionnaire avec lesquels je suis tout à fait d'accord, ce qui mène à l'avantage de la boxe et du unboxing pour un léger gain de performance.
Mais j'ai aussi lu que le dictionnaire ne renverra pas toujours les objets dans l'ordre dans lequel ils sont insérés, mais ils sont triés. Où en tant que HashTable sera. Si j'ai bien compris, cela signifie que la table de hachage est beaucoup plus rapide dans certaines situations.
Ma question est vraiment, quelles pourraient être ces situations? Est-ce que je me trompe dans mes hypothèses ci-dessus? Quelles situations utiliseriez-vous pour choisir l’une au-dessus de l’autre (oui, la dernière est un peu ambiguë).
Les classes System.Collections.Generic.Dictionary<TKey, TValue>
et System.Collections.Hashtable
maintiennent une structure de données de table de hachage en interne. Aucun d'entre eux ne garantit la préservation de l'ordre des éléments.
Laissant de côté les problèmes de boxe/unboxing, la plupart du temps, ils devraient avoir des performances très similaires.
La principale différence structurelle entre eux est que Dictionary
s'appuie sur le chaînage (en maintenant une liste d'éléments pour chaque compartiment de la table de hachage) afin de résoudre les collisions, Hashtable
utilise le rehashing pour la résolution des collisions (lorsqu'une collision se produit, essaie une autre fonction de hachage pour mapper la clé sur un compartiment).
L'utilisation de Hashtable
class présente peu d'avantages si vous ciblez pour .NET Framework 2.0+. Il est effectivement rendu obsolète par Dictionary<TKey, TValue>
.
Je suppose que cela ne vous dit rien maintenant. Mais juste pour référence pour les personnes s'arrêtant par
Test de performance - SortedList vs SortedDictionary vs Dictionnaire vs Hashtable
Dictionnaire:
Hashtable:
Une autre différence importante est que le type Hashtable prend en charge plusieurs lecteurs sans verrouillage et un seul écrivain en même temps, contrairement à Dictionary.
Article MSDN: "La classe
Dictionary<TKey, TValue>
a les mêmes fonctionnalités que la classeHashtable
. UnDictionary<TKey, TValue>
d'un type spécifique (autre queObject
) a de meilleures performances qu'unHashtable
pour les types de valeur car les éléments deHashtable
sont de typeObject
et, par conséquent, les opérations de boxing et de déballage se produisent généralement lors du stockage ou de la récupération d 'un type de valeur ".
Lien: http://msdn.Microsoft.com/en-us/library/4yh14awz (v = vs.90) .aspx
Les deux sont effectivement la même classe (vous pouvez regarder le démontage). HashTable a été créé avant que .Net ne possède des génériques. Dictionary, cependant, est une classe générique et vous offre de solides avantages en matière de frappe. Je n'utiliserais jamais HashTable puisque Dictionary ne vous coûte rien à utiliser.
Une autre différence importante est que Hashtable
est thread-safe. Hashtable
intègre une sécurité de thread à plusieurs lecteurs/graveurs uniques (MR/SW), ce qui signifie que Hashtable
autorise un enregistreur avec plusieurs lecteurs sans verrouillage. Dans le cas de Dictionary
, il n'y a pas de sécurité de thread. Si vous avez besoin de sécurité de thread, vous devez implémenter votre propre synchronisation.
Pour élaborer davantage:
Hashtable
, fournit une sécurité de thread par le biais de la propriété Synchronized, qui retourne un wrapper de thread-safe autour de la collection. Le wrapper fonctionne en verrouillant toute la collection à chaque opération d’ajout ou de suppression. Par conséquent, chaque thread qui tente d'accéder à la collection doit attendre son tour pour prendre le même verrou. Ce n'est pas évolutif et peut entraîner une dégradation significative des performances pour les grandes collections. En outre, la conception n'est pas complètement protégée des conditions de concurrence.Les classes de la collection .NET Framework 2.0 telles que
List<T>
,Dictionary<TKey, TValue>
, etc. ne fournissent aucune synchronisation de thread; Le code utilisateur doit fournir toute la synchronisation lorsque des éléments sont ajoutés ou supprimés simultanément sur plusieurs threads. Si vous avez besoin de sécurité de type ainsi que de threads, utilisez des classes de collections simultanées dans le .NET Framework. Plus de lecture ici.
Les dictionnaires ont l'avantage d'être un type générique, ce qui le rend sûr et un peu plus rapide en raison du manque de besoin de boxe. Le tableau de comparaison (construit à l’aide des réponses trouvées dans un SO question ) similaire illustre certaines des autres raisons pour lesquelles les dictionnaires gèrent les tables de hachage ( ou vice versa).
Si vous vous souciez de la lecture qui renvoie toujours les objets dans l'ordre dans lequel ils ont été insérés dans un dictionnaire, vous pouvez jeter un oeil à
OrderedDictionary - les valeurs sont accessibles via un index entier (par ordre dans lequel les éléments ont été ajoutés) SortedDictionary - les éléments sont automatiquement triés