什么时候使用元组与KeyValuePair更好?

时间:2013-10-22 15:41:38

标签: .net semantics

我通常使用KeyValuePair<TKey,TValue>类型,只要我有一对是相关的数据,因为一个是另一个的关键。如果数据不相关,则Tuple<T1,T2>类型更有意义,我会继续使用。

现在我只是阅读this article,了解为何一般避免KeyValuePair<TKey,TValue>而更喜欢Tuple<T1,T2>。主要论点是Tuple<T1,T2>的性能优势。

外界表现,有没有理由认为KVP比Tuple<T1,T2>更好?

4 个答案:

答案 0 :(得分:51)

嗯,这个类型可能被认为是名不佳的。命名的KeyValuePair应表示键和值。如果你的两个对象不是真正的关键和价值,只有两件事情怎么办?如果我要查看类型为KeyValuePair<TKey, TValue>的方法或属性,我希望KVP的值是键和值。这实际上只是沟通意图并在将来向自己表明,或者可能是其他团队成员。元组并不表示这种关联。

元组还可以更容易地添加另一个值,使其成为3元组(或三元组,但是你想要调用它)。一些.NET语言,如F#,have special syntax也围绕元组。

对于实施视角,Tuple会执行许多事情KeyValuePair。元组具有可比性,它们实现了IComparableIStructuralEquatable接口,因此可以更容易地比较两个元组。

答案 1 :(得分:36)

KeyValuePair是struct,Tuple是一个类。

这是影响对象如何通过引用或值复制的主要区别。

因此Tuple<T1,T2>传递时只使用32位操作系统中的“4byte”,而KeyValuePair<K,V>需要更多基于“K和V”

无论如何比较Tuple和KeyValuePair并不是一个好主意(对我来说没有意义)因为两者都有不同的用途。

答案 2 :(得分:18)

尽管存在语义,但考虑到两种选择,性能可能是一个重要的考虑因素。如前所述,KeyValuePair是值类型(struct),而Tuple<>是引用类型(类)。因此,KeyValuePair在堆栈上分配,Tuple<>在堆上分配,最佳选择通常由Stack vs. Heap Memory Allocation的经典参数决定。简而言之,堆栈空间有限,但通常访问速度非常快。堆内存要大得多,但速度稍慢。

如果键和值类型都是基元(KeyValuePair<T1, T2>intbool等值类型)或结构类型,则

double可能是更好的选择小尺寸。对于堆栈上的原始类型,分配和释放是快速的。 这确实会影响性能,尤其是作为递归方法调用的参数。

另一方面,如果Tuple<T1, T2>T1是引用类型(如类),T2可能是更好的选择。包含指向引用类型(作为键或值类型)的指针的KeyValuePair会破坏目的,因为无论如何都需要在堆上查找对象。

这是我在网上找到的基准:Tuple vs. KeyValuePair。此基准测试的唯一问题是他们测试KeyValuePair<string, string>Tuple<string, string>,而string类型在.NET中是一种不寻常的特殊类型,因为它可以像值类型一样运行和/或取决于执行上下文的引用类型。我相信KeyValuePair<int, int>明显胜过Tuple<int, int>。然而,即使存在缺陷,结果也表明性能差异可能很大:

  

8.23 ns - 分配元组
   0.32 ns - 分配KeyValuePair (快25倍!)

     

1.93 ns - 将Tuple作为参数传递   2.57 ns - 将KeyValuePair作为参数传递

     

1.91 ns - 返回元组
  6.09 ns - 返回KeyValuePair

     

2.79 ns - 从列表中加载元组
  4.18 ns - 从List

加载KeyValuePair

答案 3 :(得分:0)

你真正提出错误的问题正确的问题是使用类(元组)_比结构(KVP)更好,在这种情况下,答案是你想要使用它们,并在这里给出答案{{ 3}}