为什么处理Value比处理Reference for Struct更快

本文关键字:处理 Struct 更快 for Value 为什么 Reference | 更新日期: 2023-09-27 18:27:57

我可能不清楚,但当我阅读msdn文档时,我试图深入理解Struct行为。

来自msdn

处理堆栈:

这将带来性能提升。

和:

每当您需要一种将经常使用的类型时structs大多只是一段数据,可能是一个不错的选择。

我不明白,因为我想当我传递方法的Struct-in参数时,"复制值"过程一定比"复制引用"过程慢?

为什么处理Value比处理Reference for Struct更快

传递结构的成本与其大小成正比。如果结构小于引用或与引用大小相同,则传递其值的成本与传递引用的成本相同。

如果不是,那么你是正确的;复制结构可能比复制引用更昂贵。这就是为什么设计指南说要保持结构的小型化。

(请注意,当您在结构上调用方法时,"this"实际上会作为引用传递给包含结构值的变量;这就是编写可变结构的方法。)

使用structs会带来潜在的性能提升,但正如您正确指出的,也有潜在的性能损失。结构的分配(在内存和时间上)和释放(在时间上)都很便宜,如果它们很小,则复制也很便宜。引用在内存和分配时间上都稍微贵一点,在解除分配和复制方面更贵一点。如果你有大量的小结构——比如说,一百万个Point结构——那么分配和释放一个有一百万个结构的数组比分配和释放有一百万个引用Point类的一百万个实例的数组要便宜。

但是,如果结构很大,那么所有额外的复制可能比更有效的分配和释放带来的好处更昂贵。在进行绩效分析时,你必须着眼于全局;不要在没有实证数据支持的情况下,根据性能做出"结构与类"的决策。

在互联网上,在我们自己的文档中,以及在许多书中,关于C#中内存管理是如何在幕后工作的,都有很多错误信息。如果你有兴趣了解什么是神话,什么是现实,我建议你阅读我关于这个主题的系列文章。从底部开始:

http://blogs.msdn.com/b/ericlippert/archive/tags/memory+管理/

结构的另一个建议是它们应该很小;不大于16字节。这样就可以用一条指令或几个指令来复制它们。

复制相当少量的数据几乎与复制引用一样快,然后该方法访问数据的速度会更快,因为不需要重定向。

如果结构小于指针(即32或64位),则复制值甚至比复制引用更快。

即使一个结构比引用大一点,创建对象仍然会有一些开销。每个对象都有一些开销,必须作为一个单独的内存块进行分配。作为值类型的字节只占用一个字节,但如果将字节框作为对象,则它将占用堆上的16或24个字节,再加上引用的4或8个字节。


无论如何,使用结构或类的决定通常应该是关于它们所代表的数据类型,而不仅仅是性能。结构适用于表示单个实体的数据,因此可以将其视为单个值。

关于复制过程的说法是正确的,因为复制引用比复制结构花费更少的时间,因为所有结构和引用都存储在堆栈上。但是,msdn建议使用struct可以提高性能的原因是访问堆栈和堆所需的时间。

如果您需要一个主要包含静态数据且不庞大的类型(意味着它不包含值类型的多维或其他巨大数组),那么使用结构而不是引用类型会更明智,因为堆栈的访问权限远低于托管堆。

除此之外,分配和释放所需的时间,或者简而言之,与堆栈相比,堆的管理有些耗时。

你可以在这里和这里更好地理解这个主题,因为这已经被详细解释了。

希望能有所帮助。