Dans la plupart des langages de programmation, les dictionnaires sont préférés aux tables de hachage. Quelles en sont les raisons?
c#
.net
vb.net
data-structures
Nakul Chaudhary
la source
la source
Dictionary
c'était une implémentation duHashtable
.HashTable
. Quand ils ont ajouté des génériques au langage, ils ont appelé la version génériqueDictionary
. Les deux sont des tables de hachage.Réponses:
Pour ce qu'il vaut, un dictionnaire est (conceptuellement) une table de hachage.
Si vous vouliez dire "pourquoi utilisons-nous
Dictionary<TKey, TValue>
classe au lieu de laHashtable
classe?", Alors c'est une réponse simple:Dictionary<TKey, TValue>
est un type générique,Hashtable
non. Cela signifie que vous obtenez une sécurité de type avecDictionary<TKey, TValue>
, car vous ne pouvez pas insérer d'objet aléatoire dans celui-ci, et vous n'avez pas à transtyper les valeurs que vous supprimez.Fait intéressant, l'
Dictionary<TKey, TValue>
implémentation dans le .NET Framework est basée sur leHashtable
, comme vous pouvez le voir dans ce commentaire dans son code source:La source
la source
HashTable
(class) etDictionary
(class) sont des tables de hachage (concept), mais aHashTable
n'est pas unDictionary
, ni unDictionary
aHashTable
. Ils sont utilisés de façon très similaire etDictionary<Object,Object>
peuvent agir de la même manière non typée que l'aHashTable
, mais ils ne partagent pas directement de code (bien que les parties soient susceptibles d'être implémentées de manière très similaire).Dictionary
<<< >>>Hashtable
différences:Synchronized()
méthodeKeyValuePair
énuméré : <<< >>> Article énuméré:DictionaryEntry
Dictionary
/Hashtable
similitudes:GetHashCode()
méthodeCollections .NET similaires (candidats à utiliser à la place de Dictionary et Hashtable):
ConcurrentDictionary
- thread safe (accessible en toute sécurité à partir de plusieurs threads simultanément)HybridDictionary
- performances optimisées (pour quelques articles et aussi pour de nombreux articles)OrderedDictionary
- les valeurs sont accessibles via int index (par ordre dans lequel les éléments ont été ajoutés)SortedDictionary
- articles triés automatiquementStringDictionary
- fortement typé et optimisé pour les chaînesla source
StringDictionary
... btwStringDictionary
n'est pas le même queDictionary<string, string>
lorsque vous utilisez le constructeur par défaut.Parce que
Dictionary
c'est une classe générique (Dictionary<TKey, TValue>
), de sorte que l'accès à son contenu est de type sécurisé (c'est-à-dire que vous n'avez pas besoin de caster à partir deObject
, comme vous le faites avec aHashtable
).Comparer
à
Cependant,
Dictionary
est implémenté en tant que table de hachage en interne, donc techniquement, cela fonctionne de la même manière.la source
FYI: Dans .NET,
Hashtable
est thread-safe pour une utilisation par plusieurs threads de lecture et un seul thread d'écriture, tandis que dansDictionary
les membres statiques publics sont thread-safe, mais tous les membres d'instance ne sont pas garantis pour être thread-safe.Nous avons dû changer tous nos dictionnaires à
Hashtable
cause de cela.la source
ConcurrentDictionary
classe qui a toutes les méthodes publiques / protégées implémentées pour être thread-safe. Si vous n'avez pas besoin de prendre en charge les plates-formes héritées, cela vous permettrait de remplacer leHashtable
code multithread: msdn.microsoft.com/en-us/library/dd287191.aspxDans .NET, la différence entre
Dictionary<,>
etHashTable
est principalement que le premier est un type générique, donc vous obtenez tous les avantages des génériques en termes de vérification de type statique (et de boxe réduite, mais ce n'est pas aussi grand que les gens ont tendance à penser termes de performances - il y a un coût de mémoire certain pour la boxe, cependant).la source
Les gens disent qu'un dictionnaire est identique à une table de hachage.
Ce n'est pas nécessairement vrai. Une table de hachage est un moyen d' implémenter un dictionnaire. Un exemple typique à cela, et il peut être celui par défaut dans .NET dans la
Dictionary
classe, mais ce n'est pas par définition le seul.Vous pourriez tout aussi bien implémenter un dictionnaire en utilisant une liste chaînée ou un arbre de recherche, ce ne serait tout simplement pas aussi efficace (pour une métrique d'efficacité).
la source
Dictionary<K,V>
.IDictionary<K,V>
pourrait être n'importe quoi, cependant :)Collections
&Generics
sont utiles pour gérer un groupe d'objets. Dans .NET, tous les objets de collections relèvent de l'interfaceIEnumerable
, qui à son tour aArrayList(Index-Value))
&HashTable(Key-Value)
. Après .NET Framework 2.0,ArrayList
& aHashTable
été remplacé parList
&Dictionary
. Maintenant, leArraylist
&HashTable
n'est plus utilisé dans les projets de nos jours.Venant à la différence entre
HashTable
&Dictionary
,Dictionary
est générique alors que asHastable
n'est pas générique. Nous pouvons ajouter n'importe quel type d'objetHashTable
, mais lors de la récupération, nous devons le convertir en le type requis. Donc, ce n'est pas un type sûr. Maisdictionary
, tout en se déclarant, nous pouvons spécifier le type de clé et de valeur, il n'est donc pas nécessaire de transtyper lors de la récupération.Regardons un exemple:
HashTable
Dictionnaire,
la source
Dictionnaire:
Il retourne / lève une exception si nous essayons de trouver une clé qui n'existe pas.
Il est plus rapide qu'un Hashtable car il n'y a ni boxe ni déballage.
Seuls les membres statiques publics sont thread-safe.
Le dictionnaire est un type générique, ce qui signifie que nous pouvons l'utiliser avec n'importe quel type de données (lors de la création, doit spécifier les types de données pour les clés et les valeurs).
Exemple:
Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();
Dictionay est une implémentation sécurisée de Hashtable
Keys
etValues
est fortement typé.Table de hachage:
Il renvoie null si nous essayons de trouver une clé qui n'existe pas.
Il est plus lent que le dictionnaire car il nécessite la boxe et le déballage.
Tous les membres d'une table de hachage sont thread-safe,
Hashtable n'est pas un type générique,
Hashtable est une structure de données de type lâche, nous pouvons ajouter des clés et des valeurs de tout type.
la source
Dictionary.TryGetValue
L'article Examen approfondi des structures de données à l'aide de C # sur MSDN indique qu'il existe également une différence dans la stratégie de résolution des collisions :
La classe Hashtable utilise une technique appelée rehachage .
Le dictionnaire utilise une technique appelée chaînage .
la source
Depuis .NET Framework 3.5, il existe également un
HashSet<T>
qui fournit tous les avantages de laDictionary<TKey, TValue>
si vous n'avez besoin que des clés et pas de valeurs.Donc, si vous utilisez un
Dictionary<MyType, object>
et définissez toujours la valeur surnull
pour simuler la table de hachage sécurisée de type, vous devriez peut-être envisager de basculer vers leHashSet<T>
.la source
La
Hashtable
structure de données est typée de manière lâche, vous pouvez donc ajouter des clés et des valeurs de tout type à laHashtable
. LaDictionary
classe est uneHashtable
implémentation de type sécurisé , et les clés et les valeurs sont fortement typées. Lors de la création d'uneDictionary
instance, vous devez spécifier les types de données pour la clé et la valeur.la source
Notez que MSDN dit: "La classe Dictionary <(Of <(TKey, TValue>)>) est implémentée en tant que table de hachage ", et non la classe "Dictionary <(Of <(TKey, TValue>)>) est implémentée en tant que HashTable "
Le dictionnaire n'est PAS implémenté en tant que HashTable, mais il est implémenté suivant le concept d'une table de hachage. L'implémentation n'est pas liée à la classe HashTable en raison de l'utilisation de génériques, bien qu'en interne Microsoft aurait pu utiliser le même code et remplacer les symboles de type Object par TKey et TValue.
Dans .NET 1.0, les génériques n'existaient pas; c'est là que HashTable et ArrayList ont commencé à l'origine.
la source
HashTable:
La clé / valeur sera convertie en un type d'objet (boxe) lors du stockage dans le tas.
La clé / valeur doit être convertie dans le type souhaité lors de la lecture à partir du tas.
Ces opérations sont très coûteuses. Nous devons éviter autant que possible la boxe / le déballage.
Dictionnaire: variante générique de HashTable.
Pas de boxe / déballage. Aucune conversion requise.
la source
Un objet Hashtable se compose de compartiments qui contiennent les éléments de la collection. Un compartiment est un sous-groupe virtuel d'éléments dans la table de hachage, ce qui rend la recherche et la récupération plus faciles et plus rapides que dans la plupart des collections .
La classe Dictionary a les mêmes fonctionnalités que la classe Hashtable. Un dictionnaire d'un type spécifique (autre que Object) a de meilleures performances qu'une table de hachage pour les types de valeur car les éléments de la table de hachage sont de type objet et, par conséquent, la mise en boîte et la décompression se produisent généralement lors du stockage ou de la récupération d'un type de valeur.
Pour en savoir plus: Hashtable et Dictionary Collection Types
la source
Une autre différence importante est que Hashtable est thread-safe. Hashtable a une sécurité de thread intégrée pour plusieurs lecteurs / écrivain unique (MR / SW), ce qui signifie que Hashtable permet à UN écrivain avec plusieurs lecteurs sans verrouillage.
Dans le cas de Dictionary, il n'y a pas de sécurité des threads; si vous avez besoin de la sécurité des threads, vous devez implémenter votre propre synchronisation.
Pour développer davantage:
Si vous avez besoin de la sécurité des types ainsi que de la sécurité des threads, utilisez des classes de collections simultanées dans le .NET Framework. Plus de lecture ici .
Une différence supplémentaire est que lorsque nous ajoutons les entrées multiples dans Dictionnaire, l'ordre dans lequel les entrées sont ajoutées est conservé. Lorsque nous récupérons les éléments du dictionnaire, nous obtenons les enregistrements dans le même ordre que nous les avons insérés. Tandis que Hashtable ne conserve pas l'ordre d'insertion.
la source
Hashset
garanties de sécurité des threads MR / SW dans les scénarios d'utilisation qui n'impliquent pas de suppressions . Je pense qu'il a peut-être été conçu pour être entièrement sûr pour MR / SW, mais la manipulation des suppressions en toute sécurité augmente considérablement les frais de sécurité pour MR / SW. Alors que la conception deDictionary
aurait pu offrir une sécurité MR / SW à un coût minimal dans les scénarios sans suppression, je pense que MS voulait éviter de traiter les scénarios sans suppression comme "spéciaux".Une autre différence que je peux comprendre est:
Nous ne pouvons pas utiliser Dictionary <KT, VT> (génériques) avec les services Web. La raison en est qu'aucune norme de service Web ne prend en charge la norme générique.
la source
Dictionary<>
est un type générique et il est donc sûr de type.Vous pouvez insérer n'importe quel type de valeur dans HashTable et cela peut parfois lever une exception. Mais
Dictionary<int>
n'acceptera que les valeurs entières etDictionary<string>
n'acceptera que les chaînes.Il est donc préférable d'utiliser
Dictionary<>
au lieu deHashTable
.la source
Je ne pense pas que ce soit nécessairement vrai, la plupart des langues ont l'une ou l'autre, selon la terminologie qu'elles préfèrent .
En C #, cependant, la raison claire (pour moi) est que les tables de hachage C # et les autres membres de l'espace de noms System.Collections sont largement obsolètes. Ils étaient présents dans c # V1.1. Ils ont été remplacés à partir de C # 2.0 par les classes génériques dans l'espace de noms System.Collections.Generic.
la source
Selon ce que je vois en utilisant .NET Reflector :
Nous pouvons donc être sûrs que DictionaryBase utilise un HashTable en interne.
la source