我找到了一篇博客文章,其中提到C#编译器有时会决定将数组放在堆栈上而不是堆上:
通过堆栈分配来提高性能(.NET内存管理:第二部分)
这个人声称:
编译器有时也会自行决定将东西放在堆栈上。我用TestStruct2做了一个实验,在不安全的环境中分配它,在正常的环境中当我查看内存时,数组实际上已经被分配在堆栈上了。
有人可以证实吗?
我试图重复他的例子,但每次都尝试时,数组都是在堆上分配的。
如果C#编译器可以在不使用“unsafe”关键字的情况下进行这样的技巧,我对此特别感兴趣。我有一段代码,它正在处理许多小字节数组(长8-10字节),因此为每个新的byte[...]使用堆是时间和内存的浪费(特别是每个堆上的对象都需要8字节的开销,需要垃圾回收器)。 编辑:我只是想描述为什么这对我很重要:
我正在编写一个库,该库与Gemalto.NET智能卡通信,该卡可以在其中运行.net代码。当我调用返回某些内容的方法时,智能卡会返回8个字节,这些字节描述了返回值的确切类型。通过使用md5哈希和一些字节数组连接来计算这8个字节。
问题在于,当我有一个未知的数组时,我必须扫描应用程序中加载的所有程序集中的所有类型,并为每个类型计算这8个字节,直到找到相同的数组。
我不知道其他找到类型的方法,所以我正在尽可能加快速度。
编译器有时也会自行决定将东西放在堆栈上。我用TestStruct2做了一个实验,在不安全的环境中分配它,在正常的环境中当我查看内存时,数组实际上已经被分配在堆栈上了。
有人可以证实吗?
我试图重复他的例子,但每次都尝试时,数组都是在堆上分配的。
如果C#编译器可以在不使用“unsafe”关键字的情况下进行这样的技巧,我对此特别感兴趣。我有一段代码,它正在处理许多小字节数组(长8-10字节),因此为每个新的byte[...]使用堆是时间和内存的浪费(特别是每个堆上的对象都需要8字节的开销,需要垃圾回收器)。 编辑:我只是想描述为什么这对我很重要:
我正在编写一个库,该库与Gemalto.NET智能卡通信,该卡可以在其中运行.net代码。当我调用返回某些内容的方法时,智能卡会返回8个字节,这些字节描述了返回值的确切类型。通过使用md5哈希和一些字节数组连接来计算这8个字节。
问题在于,当我有一个未知的数组时,我必须扫描应用程序中加载的所有程序集中的所有类型,并为每个类型计算这8个字节,直到找到相同的数组。
我不知道其他找到类型的方法,所以我正在尽可能加快速度。
unsafe
上下文中使用Span<>
和ReadOnlySpan<>
来进行stackalloc
操作。 - starikcetin