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

Nic*_*tch 79 .net semantics

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

现在我只是阅读这篇文章,了解为什么要一般避免KeyValuePair<TKey,TValue>和偏好Tuple<T1,T2>.主要论点是性能优势Tuple<T1,T2>.

外表现,有什么理由认为KVP比一个更好的选择Tuple<T1,T2>

vcs*_*nes 54

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

元组还可以更容易地添加另一个值,使其成为3元组(或三元组,但您想要调用它).一些.NET语言,如F#,也有关于元组的特殊语法.

从实现角度来看,Tuple很多事情KeyValuePair都没有.元组是可比的,他们实施IComparableIStructuralEquatable接口,因此它可以更容易地比较两个元.

  • 此外,新的C#7.0支持新的,更简单的元组语法,使它们比KeyValuePairs更容易*和*高效工作.https://visualstudiomagazine.com/articles/2017/01/01/tuples-csharp-7.aspx (3认同)

Sri*_*vel 36

KeyValuePair是struct并且Tuple是一个类.

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

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

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

  • 他们如何达到不同的目的?请您详细说明一下。 (2认同)
  • @YakRangi 键值对旨在用作字典中键和值的容器,否则,它没有任何作用。另一方面,元组可用于将任何任意相关的成员存储在一起。此外,使用 Tuple,您可以存储多个成员,而不仅仅是 2 个。 (2认同)

Spe*_*uce 20

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

KeyValuePair<T1, T2>可能是更好的选择,如果这两个键和值的类型是基元(值类型,如int,bool,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 - 将元组作为参数
传递2.57 ns - 将KeyValuePair作为参数传递

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

2.79 ns - 从列表
4.18 ns 加载元组 - 从列表加载KeyValuePair