Malgré la sémantique, la performance peut être une considération importante lorsque vous envisagez les deux options. Comme mentionné précédemment, le KeyValuePair
est un type de valeur (struct), tandis que le Tuple<>
est un type de référence (class). 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 Allocation de mémoire sur la pile vs. le tas. En bref, l'espace de la 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
peut être le meilleur choix si les types de clé et de valeur sont des types primitifs (types de valeur comme int
, bool
, double
, etc.) ou des structs de petite taille. Avec des types primitifs sur la pile, l'allocation et la libération sont ultra rapides. Cela peut vraiment affecter les performances, surtout en tant qu'arguments pour des appels de méthode récursive.
D'autre part, Tuple
est probablement le meilleur choix si l'un des types T1
ou T2
est un type de référence (comme les classes). Un KeyValuePair
qui contient des pointeurs vers des types de référence (en tant que types de clé ou de valeur) va à l'encontre du but recherché 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
vs. Tuple
, et le type string
est un type inhabituel et spécial dans .NET en ce sens qu'il peut se comporter à la fois comme un type de valeur et/ou un type de référence en fonction du contexte d'exécution. Je pense que KeyValuePair
aurait été clairement gagnant contre Tuple
. Malgré les lacunes, cependant, les résultats montrent que les différences de performances peuvent être significatives :
8.23 ns -- Allouer Tuple
0.32 ns -- Allouer KeyValuePair (25x plus rapide!)
1.93 ns -- Passer Tuple en argument
2.57 ns -- Passer KeyValuePair en argument
1.91 ns -- Renvoyer Tuple
6.09 ns -- Renvoyer KeyValuePair
2.79 ns -- Charger Tuple depuis la liste
4.18 ns -- Charger KeyValuePair depuis la liste