C#数据局部性:结构数组中的引用类型

C#数据局部性:结构数组中的引用类型,c#,optimization,C#,Optimization,我读过很多关于数据局部性的文章,但没有找到答案:如果我创建一个结构数组来拥有一个连续的内存块(比如说MyStruct,它由值类型组成),然后向MyStruct添加一个字符串,那么字符串分配在哪里?简言之,声明为结构成员(数组中的项)的引用类型是否能够很好地获取缓存线?还是我最终获取了一个引用,然后必须找到它,这首先破坏了创建结构数组的全部目的 我相信我的措辞是正确的,但我觉得有点滑头 谢谢你抽出时间 编辑:我意识到字符串是在堆上分配的,只是想知道连续方面…引用类型总是作为独立对象在堆上分配的。它

我读过很多关于数据局部性的文章,但没有找到答案:如果我创建一个结构数组来拥有一个连续的内存块(比如说MyStruct,它由值类型组成),然后向MyStruct添加一个字符串,那么字符串分配在哪里?简言之,声明为结构成员(数组中的项)的引用类型是否能够很好地获取缓存线?还是我最终获取了一个引用,然后必须找到它,这首先破坏了创建结构数组的全部目的

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

谢谢你抽出时间


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

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

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

给定:

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

MyStruct[]的布局与string[]几乎相同——也就是说,您有一个对字符串实例的4/8字节引用的连续数组,例如,您可以在不接触非连续数据的情况下与object.ReferenceEquals(…)进行比较。然而,字符串实例本身——关于长度、散列、字符、普通相等性的数据(因为字符串重载==就这些内容而言),等等——不是这个连续块的一部分,因为字符串是引用类型

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


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

我想
struct MyClass{string Member;}
应该是
class MyClass{string Member;}
。好的捕获!编辑以修复。这非常清楚,我很感激。我没有想到“保存一层间接寻址”部分,这当然很有意义。你提到了“类型作者”。我将对此做一些研究。第一段是正确的,这很好:没有华丽的b.s.读了这篇文章后,我可以很容易地想象从数据局部性的角度来看,一个噩梦般的ref类型有ref类型有ref类型会是什么,以及为什么。Type author不是一个技术术语。是他写的课。在C++中,类型不关心它在哪里分配,因为所有可能的地方都是相同的:对象通过它的地址来标识,它总是具有那个意义上的身份(或者总是不依赖于解释)。此外,没有GetHashCode,并不是所有C++结构都是默认可构造的。这就是C++如何避免这个问题的。