web-dev-qa-db-fra.com

Efficacité des dictionnaires C #

Les dictionnaires C # sont un moyen simple de savoir si quelque chose existe, etc. Je me demande cependant comment ils fonctionnent. Disons qu'au lieu d'un dictionnaire, j'utilise une ArrayList. Au lieu d'utiliser ContainsKey (ou une méthode équivalente dans une autre langue), je passe en revue ArrayList pour vérifier si quelque chose existe (ou effectuer une recherche binaire si les données sont triées ou quelque chose de similaire). Quelle est la différence d'efficacité? La méthode ContainsKey utilise-t-elle un moyen plus efficace plutôt que de parcourir les clés et de vérifier si ce que je recherche existe?

Si disons que j'ai créé une fonction de hachage spécifique qui correspond au type de données que j'ai et qui est spécifiquement conçue pour cet ensemble de données, alors oui, cette fonction de hachage est en effet plus rapide que de parcourir les données. Mais les dictionnaires sont généraux. La méthode ContainsKey n'est pas spécifique aux données qu'elle obtient, c'est une méthode de recherche générale.

Fondamentalement, ce que je demande, c'est. Les dictionnaires sont utiles aux programmeurs. Ils incluent des méthodes qui aident à beaucoup de choses et ils combinent des chaînes avec des entiers, (clés et valeurs) et bien d'autres. Mais en matière d'efficacité, qu'offrent-ils? Quelle est la différence entre un dictionary et un ArrayList de structs(string,int)

14
John Demetriou

Vous devez creuser un peu pour voir comment le Dictionary est implémenté en C # - Ce n'est pas aussi évident que HashMap (une table de hachage) ou TreeMap (un arbre trié) (ou ConcurrentSkipListMap - a sauter la liste ).

Si vous creusez dans la section "Remarques":

La classe générique Dictionary fournit un mappage d'un ensemble de clés à un ensemble de valeurs. Chaque ajout au dictionnaire se compose d'une valeur et de sa clé associée. La récupération d'une valeur à l'aide de sa clé est très rapide, proche de O (1), car la classe Dictionary est implémentée comme une table de hachage.

Et nous l'avons. C'est un table de hachage . Notez que j'ai lié l'article Wikipédia là-bas - c'est une assez bonne lecture. Vous voudrez peut-être lire la section sur la résolution des collisions. Il est possible d'obtenir un ensemble de données pathologiques où la recherche revient à O(N) (par exemple, tout ce que vous insérez tombe dans la même valeur de hachage ou index dans la table de hachage pour une raison quelconque et vous suis laissé avec palpage linéaire ).

Bien que le dictionnaire soit une solution à usage général, vous ne devez pas contourner les types concrets (tels que le dictionnaire) - vous devez contourner les interfaces. Dans ce cas, cette interface est IDictionary ( docs ). Pour cela, vous êtes parfaitement capable d'écrire votre propre implémentation de dictionnaire qui fait les choses de manière optimale pour les données dont vous disposez.

Quant à l'efficacité de la recherche/contient divers?

  • Parcourir une liste non triée: O (N)
  • Recherche binaire d'un tableau trié: O (log N)
  • Arbre trié: O (log N)
  • Table de hachage: O (1)

Pour la plupart des gens, la table de hachage est ce qu'ils veulent.

Vous pouvez trouver que le SortedDictionary est ce que vous voulez à la place:

Le SortedDictionary<TKey, TValue> La classe générique est un arbre de recherche binaire avec récupération O (log n), où n est le nombre d'éléments dans le dictionnaire. À cet égard, il est similaire au SortedList<TKey, TValue> classe générique. Les deux classes ont des modèles d'objets similaires, et les deux ont une récupération O (log n).

Bien que, encore une fois, si la structure de données ne fonctionne pas idéalement avec vos données, vous disposez des outils (les interfaces) pour pouvoir en écrire un qui fonctionne le mieux pour vos données.

Le dictionnaire lui-même est un type de données abstrait . Vous me donnez un dictionnaire et je sais ce que je peux en faire et tous les outils là-bas pour moi d'utiliser par la nature d'être un dictionnaire. Si vous me donniez une liste de tableaux, je me retrouverais à écrire mon propre code pour rechercher, insérer ou supprimer des éléments de la liste. Cela me fait perdre du temps et signifie également qu'il y a plus de chances pour un bug que je copie le code encore et encore d'un endroit à l'autre.

22
user40980