Malgré la sémantique, les performances peuvent être une considération importante lorsque vous envisagez les deux options. Comme mentionné précédemment, the KeyValuePair
est un type valeur (struct), tandis que the Tuple<>
est un type référence (classe). Par conséquent, le KeyValuePair
est alloué sur la pile et le Tuple<>
est alloué sur le tas, et le choix optimal est généralement déterminé par les arguments classiques de l' allocation de mémoire pile ou tas . En bref, l'espace de pile est limité, mais a généralement un accès très rapide. La mémoire du tas est beaucoup plus grande mais est un peu plus lente.
KeyValuePair<T1, T2>
peut être le meilleur choix si les deux types de clés et la valeur sont primitives (types de valeur comme int
, bool
, double
, etc.) ou struct de petite taille. Avec les types primitifs sur la pile, l'allocation et la désallocation sont rapides comme l'éclair. Cela peut vraiment affecter les performances, en particulier en tant qu'arguments aux appels de méthode récursifs.
D'autre part, Tuple<T1, T2>
est probablement le meilleur choix si l'un T1
ou l' autre T2
des types de référence (comme les classes). Un KeyValuePair
qui contient des pointeurs vers des types de référence (comme les types de clé ou de valeur) va en quelque sorte à l'encontre de l'objectif puisque les objets devront de toute façon être recherchés sur le tas.
Voici un benchmark que j'ai trouvé en ligne: Tuple vs KeyValuePair . Le seul problème avec ce benchmark est qu'ils ont testé KeyValuePair<string, string>
contre Tuple<string, string>
, et le string
type est un type inhabituel et spécial dans .NET en ce qu'il peut se comporter à la fois comme un type valeur et / ou un type référence en fonction du contexte d'exécution. Je crois que l' KeyValuePair<int, int>
aurait été un vainqueur clair contre Tuple<int, int>
. Cependant, même avec les lacunes, les résultats montrent que les différences de performance peuvent être importantes:
8.23 ns - Allocate Tuple
0.32 ns - Allocate KeyValuePair (25x plus rapide!)
1,93 ns - Passez Tuple comme argument
2,57 ns - Passez KeyValuePair comme argument
1,91 ns -
Tuple de retour 6,09 ns - Retour KeyValuePair
2.79 ns - Charger le tuple de la liste
4.18 ns - Charger la KeyValuePair depuis la liste
KeyValuePair
est une clé et une valeur, aTuple<T1,T2>
est juste une paire de valeurs égales . Vous pouvez également demander: "pourquoi devrais-je utiliser unList<Class>
si je peux utiliserDictionary<A,B>
".