在C#中,当使用值类型数组或引用类型数组时,数据会更密集地组合在一起吗?
我的理由是结构数组将所有数据放在一起就在这里,现在,而对于引用类型(所有引用都在一起)也是如此,它们可以到处都是。
(我意识到鼓励尽可能使用C#的集合接口,并且可读代码胜过过早的优化,但我只是对它是如何工作感到好奇。)
答案 0 :(得分:2)
这取决于你如何定义密集包装。是的,引用将遍布整个地方,但您还应该考虑分配数组所需的内存大小。
引用数组将需要一个较小的连续内存块,然后是一个大型结构数组。结构将以内联方式存储,因此每个数组元素将彼此远离。使用引用时,每个数组元素本质上都是指向引用的指针,因此每个元素都较小,因此元素更靠近。
要考虑的另一个问题是数组需要连续的内存块。如果在大对象堆上分配,因为碎片是一个问题,因为它没有被GC压缩,那么你更有可能因较大的数组而失去内存异常。即使你有足够的可用内存,由于碎片,你可能没有足够的免费连续内存。大型结构数组将需要比引用数组更多的连续内存。
这不是真正直接适用的,而是在考虑数组的内存要求时需要考虑的其他事项。使用具有Capacity属性的基础类型的数组的集合通常通过分配两倍于前一个大小的新数组并将元素复制到新数组来增加集合。这意味着如果您有256个项目的集合并添加257个项目,则会分配一个新的512元素数组并将项目复制到该项目。 256项数组将被释放,但在复制过程中,集合需要768个项目的内存(但不是连续的,256个数组+ 512个数组)。因此,您可以为512个项目提供足够的可用内存,但不足以满足700项目,因此增加收集将因内存不足而失败,因为您尝试添加第257个项目。因此,有时,增加一个集合所需的内存大约是目前占用的内存的3倍。结合连续的内存要求,当你看来你有足够的内存时,你可以得到内存不足的异常。
答案 1 :(得分:1)
如果您正在谈论处理器实际上会咀嚼的数据 - 那么是的,结构更“密集”(即,它不是需要解除引用的内存地址)。
你需要更清楚你想要实现的目标 - 听起来你正在尝试优化某些东西,将类数组更改为结构数组并不一定会更快。它取决于您的数据以及您尝试使用它的方式。