2017-06-30 3 views
3

Ici, j'ajouter quelque chose à un Dictionary:Clé du dictionnaire ArgumentException duplicate: quelle est la plus performante?

dictionary.Add(dictionaryKey, value); 

si dictionaryKey existe déjà, un ArgumentException sera lancé. Son message est assez générique:

Un article avec la même clé a déjà été ajouté.

Si mon appel à dictionary.Add est à l'intérieur d'une boucle ou une fonction d'aide, il peut être difficile de dire immédiatement ce que la clé a déjà été ajouté que cette exception est de lancer. Je voudrais le savoir aussi facilement et le plus tôt possible.

Il existe plusieurs options.

1)

if(dictionary.ContainsKey(dictionaryKey) 
{ 
    throw new ArgumentException($"An item with the same key ({dictionaryKey}) has already been added."); 
} 

dictionary.Add(dictionaryKey, value); 

2)

try 
{ 
    dictionary.Add(dictionaryKey, value); 
} 
catch(ArgumentException argumentException) 
{ 
    throw new ArgumentException($"An item with the same key ({dictionaryKey}) has already been added."); 
} 

3) Une autre façon

Je sais que la mise en place d'un bloc try/catch prend un coup de performance, mais il semble courir dictionary.ContainsKey(dictionaryKey) signifierait une recherche supplémentaire à chaque fois aussi. Laquelle de ces options est la plus performante?

+1

J'irais avec la première approche car le dictionnaire contient seulement la complexité O (1). Le traitement des exceptions ne doit pas être utilisé dans ce cas. –

+1

Essayer/attraper des blocs ne provoque aucun coup de performance, c'est le lancement d'une exception qui fait –

+0

Ne devrait-il pas déjà y avoir une indication dans le message d'erreur de ce qui était en train d'être inséré? – jth41

Répondre

1

Vous ne savez pas où se situe le contexte de ce code, mais en termes de performances, cela dépend si vous attendez dictionaryKey s.

S'il va y avoir des doublons, je vais avec la première méthode, comme ContainsKey est un O (1) opération, alors que try/catch encourt une small performance penalty si elle est utilisée pour gérer le flux de contrôle. Vraisemblablement, cette pénalité sera supérieure à O (1).

Toutefois, si vous ne pouvez pas garantir la duplication de dictionaryKey s, la seconde méthode serait plus rapide. La pénalité de performance try/catch se produit uniquement si une exception est levée (une clé en double est trouvée). La première méthode effectuera un appel inutile à ContainsKey. Bien sûr, cela signifie que vous n'avez pas besoin d'envelopper le code dans un try/catch en premier lieu, ce qui va à l'encontre du but de votre question.

J'irais avec la première méthode.