KeyValuePairよりもタプルを使用する方が良いのはいつですか?


91

私は通常KeyValuePair<TKey,TValue>、一方が他方の鍵であるという意味でペアに関連するデータがある場合は常にこのタイプを使用しました。データが関連していない場合は、Tuple<T1,T2>タイプの方が理にかなっているので、それを使用します。

今、私は一般的に避けて好む理由についてこの記事を読んだだけです。主な議論は、のパフォーマンス上の利点です。KeyValuePair<TKey,TValue>Tuple<T1,T2>Tuple<T1,T2>

パフォーマンス以外で、KVPがより良い選択である理由はありますTuple<T1,T2>か?


4
AKeyValuePairはキーと値であり、aTuple<T1,T2>等しい値のペアです。また、「使用List<Class>できるのに、なぜを使用する必要があるのか​​」と尋ねることもできますDictionary<A,B>
Tim Schmelter 2013年

4
そうですが、その場合はキーを使用してデータを検索できます。それは何かを意味します。この場合は、名前だけで意味は、彼らがいない平均何でもやる、ある(プロセッサにする。)
ニック・ゴッチ

1
タプルは等しい値のペアではなく、いくつかの等しいタイプです。たぶんこれはつまらないものと見なされますが、たとえばCには、等しい値のさまざまな表現のためのユニオン構造があります。:)
Jonas

回答:


68

ええと、そのタイプは、1つには不十分な名前と見なされる可能性があります。名前付きのKeyValuePairは、キーと値を表す必要があります。2つのオブジェクトが実際にはキーと値ではなく、2つだけである場合はどうなりますか?のタイプを持つメソッドまたはプロパティを見るKeyValuePair<TKey, TValue>と、KVPの値がキーと値であることが期待されます。これは実際には、意図を伝え、将来自分自身、またはおそらく他のチームメンバーにそれを明確にすることの問題です。タプルは、そのような関連付けを示すものではありません。

タプルを使用すると、別の値を簡単に追加できるため、3タプル(またはトリプレット、ただし、呼び出したい場合)になります。F#などの一部の.NET言語には、タプルの周りにも特別な構文があります

実装の観点からすると、Tuple多くのことKeyValuePairはしません。タプルは比較可能であり、IComparableIStructuralEquatableインターフェイスを実装しているため、2つのタプルを簡単に比較できます。


1
KeyValuePairsを辞書に入れるのは難しい方法を見つけましたが、当時は結果が得られませんでした。
MKesper 2016

3
さらに、新しいC#7.0は、タプルの新しい単純な構文をサポートしているため、KeyValuePairsよりもはるかに簡単パフォーマンスが高くなります。visualstudiomagazine.com/articles/2017/01/01/...
ジェイコブスタム

1
また、タプルでパラメーターに名前を付ける機能により、消費者はパラメーターが何に使用されるのかを理解しやすくなります。KVPのような一般的なものでは、それは実際には誰もが推測します-どこかに具体的に文書化されていない限り-キーが「ある」と想定されているもの-つまり、そのタイプではなく、設定名や社会保障などの現実世界のものです
社会

40

KeyValuePairは構造体でTupleあり、クラスです。

これが、参照または値によるオブジェクトのコピー方法に影響を与える主な違いです。

したがってTuple<T1,T2>、渡されると、32ビットOSでは「4byte」を使用するだけですが、「KandV」にKeyValuePair<K,V>基づくものがさらに必要になります。

とにかく、TupleとKeyValuePairを比較することは良い考えではありません(私には意味がありません)。どちらも目的が異なるためです。


3
それらはどのように異なる目的を果たしますか?それについて詳しく説明していただけませんか。
OldSchool 2017

2
@YakRangi keyvaluepairは、ディクショナリ内のキーと値のコンテナとして使用することを目的としています。それ以外の場合は、目的を果たしません。一方、タプルは、任意に関連するメンバーを一緒に格納するために使用できます。また、タプルであなただけではなく2組み合わせた複数のメンバー保存することができます
スリラムSakthivel

1
@SriramSakthivelこれは、OPの質問に対する答えは、辞書を参照している場合を除いて、KVPを使用しないことを意味します。
AlexFainshtein19年

24

セマンティクスにもかかわらず、両方のオプションを検討する場合、パフォーマンスは重要な考慮事項になる可能性があります。前述のように、KeyValuePairは値型(struct)であるのに対し、Tuple<>は参照型(class)です。したがって、はKeyValuePairスタックにTuple<>割り当てられ、はヒープに割り当てられます。最適な選択は通常、スタックとヒープメモリの割り当ての古典的な引数によって決定されます。要するに、スタックスペースは限られていますが、一般的に非常に高速にアクセスできます。ヒープメモリははるかに大きくなりますが、やや遅くなります。

KeyValuePair<T1, T2>キーと値の両方のタイプは、プリミティブ(値型が好きであれば良い選択であり得るintbooldouble、など)または小型の構造体。スタックにプリミティブ型があるため、割り当てと割り当て解除は非常に高速です。これは、特に再帰的なメソッド呼び出しへの引数として、パフォーマンスに実際に影響を与える可能性があります。

一方、またはが参照型(クラスなど)であるTuple<T1, T2>場合は、おそらくより適切な選択です。とにかくオブジェクトをヒープ上で検索する必要があるため、参照型(キーまたは値型として)へのポインターを含むAは、目的を打ち破ります。T1T2KeyValuePair

これが私がオンラインで見つけたベンチマークです:タプル対KeyValuePair。このベンチマークの唯一の問題は、KeyValuePair<string, string>vs Tuple<string, string>。をテストしたことです。このstring型は、実行コンテキストに応じて値型や参照型の両方のように動作できるという点で、.NETでは珍しい特殊な型です。KeyValuePair<int, int>に対して明らかに勝者だったと思いますTuple<int, int>。ただし、欠陥がある場合でも、結果はパフォーマンスの違いが大きくなる可能性があることを示しています。

8.23 NS -タプル割り当て
0.32ナノ秒- KeyValuePair割り当て(25倍高速化を!)

1.93ns-タプルを引数
として渡す2.57ns-KeyValuePairを引数として渡す

1.91ns-タプルを
返す6.09ns-KeyValuePairを返す

2.79ns-リストからタプルを
ロード4.18ns-リストからKeyValuePairをロード


0

あなたが本当に間違った質問をするのは、適切な質問はStruct(KVP)よりもClass(Tuple)_を使用することです。その場合、答えはそれらを何に使用したいかであり、答えはここに構造体とクラスが示されています。


2
彼は正しい質問をした。どの使用法が明示的に暗示されているかについて、どちらが優れているかという問題。
グレッグ

@グレッグは、質問は、より良いチョコレートやソーダであるであるが、特定の質問は無意味であるとより良い食べ物や飲み物に関する一般的な質問として扱わ
MikeT

3
事実上の質問は、「タプルとキーペアをいつ使用する必要があるか」です。これは正当な質問です。あなたは「より良い」という言葉の意味論に固執していると思います。
グレッグ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.