通常,KeyValuePair<TKey,TValue>
只要我拥有与数据对相关的数据,就使用一种类型,因为一个是另一个的关键。如果数据不相关,则Tuple<T1,T2>
类型更有意义,我会考虑。
现在,我只读了这篇文章,了解为什么通常要避免KeyValuePair<TKey,TValue>
和偏爱Tuple<T1,T2>
。主要的争论是绩效的收益Tuple<T1,T2>
。
外部表现,有什么理由比KVP更好Tuple<T1,T2>
?
通常,KeyValuePair<TKey,TValue>
只要我拥有与数据对相关的数据,就使用一种类型,因为一个是另一个的关键。如果数据不相关,则Tuple<T1,T2>
类型更有意义,我会考虑。
现在,我只读了这篇文章,了解为什么通常要避免KeyValuePair<TKey,TValue>
和偏爱Tuple<T1,T2>
。主要的争论是绩效的收益Tuple<T1,T2>
。
外部表现,有什么理由比KVP更好Tuple<T1,T2>
?
Answers:
好吧,该类型可以被认为是名字不好的一个。名为KeyValuePair的名称应表示一个键和一个值。如果您的两个对象实际上不是键和值,仅仅是两件事怎么办?如果我看到类型为的方法或属性,则KeyValuePair<TKey, TValue>
希望KVP的值是键和值。这实际上只是沟通意图并在将来向自己或其他团队成员明确表示问题。元组不表示这种关联。
元组还使添加另一个值变得更容易,使它成为3元组(或三元组,不过您想调用它)。某些.NET语言(例如F#)具有特殊的语法在元组周围。
从实现的角度来看,Tuple
很多事情KeyValuePair
没有。元组具有可比性,它们实现IComparable
和IStructuralEquatable
接口,因此可以更轻松地比较两个元组。
KeyValuePair
是struct,Tuple
是一个类。
那是主要的差异,这会影响通过引用还是通过值复制对象的方式。
因此Tuple<T1,T2>
在32位操作系统中传递时仅使用“ 4byte”,而KeyValuePair<K,V>
基于“ K和V”则需要更多
无论如何,比较Tuple和KeyValuePair并不是一个好主意(对我而言这没有意义),因为两者都有不同的用途。
尽管具有语义,但是在您同时考虑这两个选项时,性能可能是一个重要的考虑因素。如前所述,KeyValuePair
是值类型(结构),而是Tuple<>
引用类型(类)。因此,KeyValuePair
分配在堆栈上,Tuple<>
分配在堆上,最佳选择通常由堆栈与堆内存分配的经典参数确定。简而言之,堆栈空间有限,但通常访问速度非常快。堆内存要大得多,但要慢一些。
KeyValuePair<T1, T2>
可能是更好的选择,如果这两个键和值的类型是基元(值类型喜欢int
,bool
,double
等),或小尺寸的结构。在堆栈上使用原始类型时,分配和取消分配的速度很快。这确实会影响性能,尤其是作为递归方法调用的参数时。
在另一方面,Tuple<T1, T2>
很可能是更好的选择,如果任一T1
或T2
是引用类型(如类)。KeyValuePair
包含指向引用类型(作为键或值类型)的指针的A达不到目的,因为无论如何都需要在堆上查找对象。
这是我在网上找到的基准:Tuple与KeyValuePair。该基准测试的唯一问题是他们测试了KeyValuePair<string, string>
vs. 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-返回KeyValuePair2.79 ns-从列表中加载元组
4.18 ns-从列表中加载KeyValuePair
KeyValuePair
是键和值,aTuple<T1,T2>
只是一对相等的值。您也可能会问:“List<Class>
如果可以使用,为什么要使用aDictionary<A,B>
”。