80 votes

Récupération des valeurs du dictionnaire - Meilleures pratiques

J'ai récemment remarqué Dictionary.TryGetValue(TKey key, out TValue value) et j'étais curieux de savoir quelle était la meilleure approche pour récupérer une valeur dans le dictionnaire.

Je l'ai toujours fait :

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
     ...

à moins que je ne le sache a pour être là-dedans.

Est-ce que c'est mieux de faire juste :

if (myDict.TryGetValue(somekey, out someVal)
    ...

Quelle est la meilleure pratique ? L'une est-elle plus rapide que l'autre ? J'imagine que la version Try serait plus lente car elle "avale" un try/catch en son sein et l'utilise comme logique, non ?

Merci !

85voto

Micah Points 28683

TryGetValue est légèrement plus rapide, car FindEntry ne sera appelé qu'une seule fois.

Plus rapide de combien ? Cela dépend de l'ensemble ensemble de données à disposition. Lorsque vous appelez la méthode Contains, le dictionnaire effectue une recherche interne pour trouver son index. Si il renvoie un résultat positif, vous devez recherche d'index pour obtenir la valeur réelle. Lorsque vous utilisez la méthode TryGetValue, elle recherche une seule fois l'index et s'il est trouvé, il attribue la valeur à votre variable.

Pour info : il n'y a pas vraiment d'erreur.

C'est un appel :

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;
}

ContainsKey, c'est ça :

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

0 votes

TryGetValue est légèrement plus rapide, car FindEntry n'est appelé qu'une seule fois.

1 votes

TryGetValue est beaucoup plus rapide lorsque vous avez un grand Dictionnaire

4 votes

En théorie (et aussi en pratique), cela ne devrait pas dépendre de la taille du dictionnaire, puisque le temps de recherche attendu ( !) est constant, c'est-à-dire indépendant de la taille du dictionnaire !

29voto

Diadistis Points 6892

En fait, TryGetValue est plus rapide. Plus rapide de combien ? Cela dépend de l'ensemble de données en question. Lorsque vous appelez la méthode Contains, le dictionnaire effectue une recherche interne pour trouver son index. S'il renvoie vrai, vous devez effectuer une autre recherche d'index pour obtenir la valeur réelle. Lorsque vous utilisez TryGetValue, il ne cherche qu'une seule fois l'index et, s'il est trouvé, il attribue la valeur à votre variable.

Edit :

Ok, je comprends votre confusion, alors laissez-moi développer :

Cas 1 :

if (myDict.Contains(someKey))
     someVal = myDict[someKey];

Dans ce cas, il y a deux appels à FindEntry, l'un pour vérifier si la clé existe et l'autre pour la récupérer.

Cas 2 :

myDict.TryGetValue(somekey, out someVal)

Dans ce cas, il n'y a qu'un seul appel à FindKey car l'index résultant est conservé pour la récupération effective dans la même méthode.

0 votes

Il s'agit d'un accord. TryGetValue élimine la nécessité d'effectuer deux fois la recherche de la clé. Il peut également s'avérer utile en cas de multithreading. Entre le moment où vous vérifiez si la valeur existe, elle peut avoir été ajoutée ou supprimée. Cela peut entraîner des exceptions du type "la clé existe déjà" ou "la clé n'a pas été trouvée".

0voto

Jennifer Points 2603

J'imagine que trygetvalue fait plutôt quelque chose comme :

if(myDict.ReallyOptimisedVersionofContains(someKey))
{ 
  someVal = myDict[someKey];
  return true;
}
return false;

J'espère donc qu'il n'y aura pas de try/catch.

Je pense que c'est juste une méthode de commodité, vraiment. Je l'utilise généralement car elle permet d'économiser une ou deux lignes de code.

0voto

dubi Points 1007
    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;
}

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

Comme vous pouvez le voir, TryGetValue est identique à ContainsKey + une recherche dans le tableau.

Si votre logique consiste uniquement à vérifier si la clé existe dans le dictionnaire et si rien d'autre n'est lié à cette clé (en prenant la valeur de la clé), vous devriez utiliser ContainsKey.

Essayez aussi de vérifier cette question similaire : Y a-t-il une raison pour laquelle on devrait utiliser la valeur "contient" plutôt que la valeur "tryget" ?

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