c# Data Locality:结构数组中的引用类型

本文关键字:引用类型 数组 结构 Data Locality | 更新日期: 2023-09-27 18:05:47

我已经阅读了相当多的数据位置帖子,但没有找到答案:如果我创建一个结构数组,以便有一个连续的内存块(让我们说MyStruct,这是由值类型组成),然后添加一个字符串到我的MyStruct,在哪里分配字符串?简而言之,作为结构体(数组中的项)成员声明的引用类型是否可以很好地获取缓存行?或者我最终是否获取了一个引用,然后必须对其进行定位,这首先破坏了创建结构数组的整个目的?

我相信我的措辞是正确的,但我觉得它有点滑。

感谢您的宝贵时间。

编辑:我意识到字符串是在堆上分配的,只是想知道连续的方面…

c# Data Locality:结构数组中的引用类型

给定:

struct MyStruct { string Member; } class MyClass { string Member; }

MyStruct[]将具有与string[]几乎相同的布局-也就是说,您有一个连续的4/8字节引用字符串实例的数组,您可以与object.ReferenceEquals(…)进行比较,而无需接触非连续数据。然而,字符串实例本身——关于长度、哈希、字符、普通相等(因为字符串在这些方面重载==)等的数据——不是这个连续块的一部分,因为字符串是一种引用类型。

这仍然比MyClass[]好,但是,MyClass[]将是一个连续的数组,包含4/8字节 MyClass实例的引用-也就是说,MyClass实例本身不会是连续的-反过来又有另一个 4/8字节对字符串的引用,这也不会是连续的。

因此,有意义地使用Member意味着你几乎肯定会处理一些非连续数据,但是使用struct仍然会为你节省一层间接。

引用类型总是作为独立对象在堆上分配。它们永远不会内联到其他东西。

类型作者选择分配样式,类型用户没有选择。这是因为实现通常依赖于分配语义。如果你强迫许多类像结构一样工作,它们就不能正常工作。