为什么在.NET 4.0中引用类型(类)的新的元组类型,而不是一个值类型(结构) [英] Why is the new Tuple type in .Net 4.0 a reference type (class) and not a value type (struct)

查看:166
本文介绍了为什么在.NET 4.0中引用类型(类)的新的元组类型,而不是一个值类型(结构)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道答案和/或有oppinion呢?

Does anyone know the answer and/or have an oppinion about it?

由于元组通常不会很大我相信它会更合理使用结构比类此。你说什么?

Since tuples would normally not be very large I would assume it would make more sense to use structs than classes for these. What say you?

推荐答案

微软所做的所有元组类型的引用类型在简单的利益。

Microsoft made all tuple types reference types in the interests of simplicity.

我个人认为这是一个错误。元组有4个以上的领域是非常不寻常的,应该有更多的有类型的替代反正取代(如F#中的记录类型),因此只小的元组是实际利益。我自己的基准测试表明,拆箱元组最多512个字节仍然能比盒装元组快。

I personally think this was a mistake. Tuples with more than 4 fields are very unusual and should be replaced with a more typeful alternative anyway (such as a record type in F#) so only small tuples are of practical interest. My own benchmarks showed that unboxed tuples up to 512 bytes could still be faster than boxed tuples.

虽然内存效率是关注的,我相信主要的问题是.NET垃圾收集器的开销。分配和收集是的非常昂贵的.NET平台,因为它的垃圾回收器一直都不是很严重的优化(例如相比于JVM)。此外,默认.NET的GC(工作站)尚未并行化。因此,使用元组并行程序停顿下来,因为所有内核争用共享的垃圾收集器,摧毁的可扩展性。这不仅是主要关心的问题,但是,AFAIK,完全被微软忽视时,他们研究了这一问题。

Although memory efficiency is one concern, I believe the dominant issue is the overhead of the .NET garbage collector. Allocation and collection are very expensive on .NET because its garbage collector has not been very heavily optimized (e.g. compared to the JVM). Moreover, the default .NET GC (workstation) has not yet been parallelized. Consequently, parallel programs that use tuples grind to a halt as all cores contend for the shared garbage collector, destroying scalability. This is not only the dominant concern but, AFAIK, was completely neglected by Microsoft when they examined this problem.

另一个值得关注的是虚拟的调度。引用类型支持亚型,因此,它们的成员通常经由虚拟调度调用。与此相反,值类型不能支持这样的亚型成员调用是完全明确的,并且总是可以作为直接函数调用执行。虚拟调度是现代的硬件非常昂贵的,因为CPU不能predict程序计数器将结束。在JVM继续不遗余力地优化虚拟调度,但.NET没有。然而,.NET确实提供了从虚拟调度逃生的值类型的形式。所以,再presenting元组的值类型可能再次有了显着提高了在这里的表现。例如,调用 GetHash code 在2元组一百万次需要0.17s,但在同等结构调用它只有0.008s需要,即值类型比引用类型20×更快。

Another concern is virtual dispatch. Reference types support subtypes and, therefore, their members are typically invoked via virtual dispatch. In contrast, value types cannot support subtypes so member invocation is entirely unambiguous and can always be performed as a direct function call. Virtual dispatch is hugely expensive on modern hardware because the CPU cannot predict where the program counter will end up. The JVM goes to great lengths to optimize virtual dispatch but .NET does not. However, .NET does provide an escape from virtual dispatch in the form of value types. So representing tuples as value types could, again, have dramatically improved performance here. For example, calling GetHashCode on a 2-tuple a million times takes 0.17s but calling it on an equivalent struct takes only 0.008s, i.e. the value type is 20× faster than the reference type.

一个真实的情况与元组这些性能问题通常发生在使用元组作为字典键。其实,我偶然发现了这个线程按照从堆栈溢出问题链接F#运行我算法比Python慢​​!笔者所在的F#项目横空出世,因为他是用盒装元组是比他的Python precisely慢。使用手写手工拆箱结构类型,使他的F#程序快几倍,而且比Python更快。这些问题将永远不会出现了由值类型psented如果元组进行了重新$ P $,而不是引用类型开始说起...

A real situation where these performance problems with tuples commonly arises is in the use of tuples as keys in dictionaries. I actually stumbled upon this thread by following a link from the Stack Overflow question F# runs my algorithm slower than Python! where the author's F# program turned out to be slower than his Python precisely because he was using boxed tuples. Manually unboxing using a hand-written struct type makes his F# program several times faster, and faster than Python. These issues would never had arisen if tuples were represented by value types and not reference types to begin with...

这篇关于为什么在.NET 4.0中引用类型(类)的新的元组类型,而不是一个值类型(结构)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆