283 votes

Qu'est-ce qui est le plus efficace: Dictionary TryGetValue ou ContainsKey + Item?

À partir de MSDN son entrée sur le Dictionnaire.TryGetValue Méthode:

Cette méthode combine les fonctionnalités de la ContainsKey méthode et les propriétés de l'Élément.

Si la clé n'est pas trouvée, alors la valeur du paramètre devient approprié la valeur par défaut pour le type de valeur TValue; par exemple, le 0 (zéro) pour les types integer, false pour les types Boolean, et null pour les types référence.

Utiliser le TryGetValue méthode si votre code fréquemment des tentatives d'accès les touches qui ne sont pas dans le dictionnaire. L'utilisation de cette méthode est de plus efficace que de rattraper le KeyNotFoundException jeté par l'Élément de la propriété.

Cette méthode s'approche d'un O(1).

À partir de la description, il n'est pas clair s'il est plus efficace ou plus pratique que d'appeler ContainsKey et ensuite de faire de la recherche. La mise en œuvre de l' TryGetValue appelez simplement ContainsKey et le Point ou est en fait plus efficace qu'en faisant une simple recherche?

En d'autres termes, ce qui est le plus efficace (c'est à dire que l'on effectue moins de recherches):

Dictionary<int,int> dict;
//...//
int ival;
if(dict.ContainsKey(ikey))
{
  ival = dict[ikey];
}
else
{
  ival = default(int);
}

ou

Dictionary<int,int> dict;
//...//
int ival;
dict.TryGetValue(ikey, out ival);

[Modifier] Je ne suis pas à la recherche pour une référence!!!

355voto

Reed Copsey Points 315315

``sera plus rapide.

utilise la même vérification comme , qui se réfère à l’interne à l’emplacement de l’entrée effective. Le propriété a réellement fonctionnalité code presque identique que , sauf qu’il lèvera une exception au lieu de retourner false.

À l’aide de `` suivi par l’élément fondamentalement duplique la fonctionnalité de recherche, qui est la plus grande partie du calcul dans ce cas.

95voto

dasblinkenlight Points 264350

Un rapide benchmark montre que TryGetValue a un léger avantage:

    static void Main() {
        var d = new Dictionary<string, string> {{"a", "b"}};
        var start = DateTime.Now;
        for (int i = 0; i != 10000000; i++) {
            string x;
            if (!d.TryGetValue("a", out x)) throw new ApplicationException("Oops");
            if (d.TryGetValue("b", out x)) throw new ApplicationException("Oops");
        }
        Console.WriteLine(DateTime.Now-start);
        start = DateTime.Now;
        for (int i = 0; i != 10000000; i++) {
            string x;
            if (d.ContainsKey("a")) {
                x = d["a"];
            } else {
                x = default(string);
            }
            if (d.ContainsKey("b")) {
                x = d["b"];
            } else {
                x = default(string);
            }
        }
   }

Ce produit

00:00:00.7600000
00:00:01.0610000

faire de l' ContainsKey + Item accès à environ 40% plus lent dans l'hypothèse d'un même mélange de hits et de justesse.

De plus, lorsque je modifie le programme de toujours manquer (c'est à dire toujours à la recherche jusqu' "b") les deux versions de devenir tout aussi rapide:

00:00:00.2850000
00:00:00.2720000

Lorsque je fais "tous les coups", cependant, l' TryGetValue reste un gagnant clair:

00:00:00.4930000
00:00:00.8110000

60voto

Rado Points 1999

Depuis aucune réponse à ce jour réellement répondre à la question, ici, est une réponse acceptable, j'ai trouvé après quelques recherches:

Si vous décompiler TryGetValue vous voyez que c'est de faire ceci:

public bool TryGetValue(TKey key, out TValue value)
{
  int index = this.FindEntry(key);
  if (index >= 0)
  {
    value = this.entries[index].value;
    return true;
  }
  value = default(TValue);
  return false;
}

alors que la ContainsKey méthode est la suivante:

public bool ContainsKey(TKey key)
{
  return (this.FindEntry(key) >= 0);
}

donc TryGetValue est juste ContainsKey plus un tableau de recherche si l'élément est présent.

Source

Il semble que TryGetValue sera presque deux fois plus rapide que ContainsKey+la combinaison de l'Élément.

11voto

CodesInChaos Points 60274

Pourquoi ne pas vous le tester ?

Mais je suis assez sûr que `` est plus rapide, car il ne le fait une liste de choix. Bien sûr ce n’est pas garanti, c'est-à-dire les différentes implémentations pourraient avoir des caractéristiques de performances différentes.

La façon dont je mettrait en œuvre un dictionnaire est en créant un interne `` fonction qui détecte l’emplacement d’un élément et ensuite construire le reste en plus de cela.

5voto

davisoa Points 3559

Faire un programme de test rapide, il y a certainement une amélioration à l’aide de TryGetValue avec 1 million d’éléments dans un dictionnaire.

Résultats :

ContainsKey + Item pour 1000000 hits : 45ms

TryGetValue pour 1000000 hits : 26ms

Voici l’application de test :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X