是使用值类型数组还是引用类型数组更密集地填充数据

本文关键字:数组 数据 填充 类型 引用类型 | 更新日期: 2023-09-27 18:28:34

在C#中,使用值类型数组还是使用引用类型数组时,数据会更密集地打包在一起?

我的推理是,一个结构数组将所有数据放在一起就在这里,现在,虽然引用类型也是如此(所有引用都在一起),但它们可以指向各处。

(我意识到鼓励尽可能使用C#的集合接口,可读代码胜过过早的优化,但我只是好奇它是如何工作的。)

是使用值类型数组还是引用类型数组更密集地填充数据

这取决于如何定义密集封装。是的,引用会到处都是,但您也应该考虑分配数组所需的内存大小。

一个引用数组将需要一个更小的连续内存块,而不是一个大结构数组。结构将以内联方式存储,因此每个数组元素将彼此相距更远。对于引用,每个数组元素本质上都是指向引用的指针,因此每个元素都更小,因此元素之间的距离更近。

另一个需要考虑的问题是,数组需要一个连续的内存块。如果分配在大对象堆上,其中碎片是一个问题,因为GC没有压缩它,那么对于较大的数组,您更有可能出现内存不足的异常。即使您有足够的可用内存,也可能由于碎片而没有足够的可用连续内存。与引用数组相比,大型结构数组将需要更多的连续内存。

这并不直接适用,但在考虑阵列的内存需求时需要考虑其他因素。使用数组作为基础类型(具有Capacity属性)的集合通常通过分配一个两倍于前一个数组大小的新数组并将元素复制到新数组来扩展集合。这意味着,如果您有一个256项的集合,并添加第257项,则会分配一个新的512元素数组,并将这些项复制到其中。256项数组将被释放,但在复制过程中,该集合需要768项的内存(但不是连续的,256数组+512数组)。因此,您可以有足够的可用内存来容纳512个项目,但不足以容纳700个项目,因此,仅仅因为您试图添加第257个项目,就无法增长集合,并出现内存不足异常。因此,有时,增长一个集合所需的内存是当前所占内存的3倍左右。再加上连续内存需求,当您看起来有足够的内存时,您可以获得内存不足的异常。

如果您谈论的是处理器将实际处理的数据,那么是的,结构更"密集"(即,它不是需要取消引用的内存地址)。

不过,你需要更加清楚你试图实现的目标——听起来你正在试图优化一些东西,将一组类更改为一组结构并不一定会更快。这将取决于你的数据是什么以及你试图如何使用它。