字节与内存中的字节数组

Cod*_*per 3 c# byte

下面的代码使用1个字节的内存.

byte[] n = new byte[] { 10, 20, 30, 40 }; //memory looks like this 10 | 20 | 30 | 40
Run Code Online (Sandbox Code Playgroud)

vs下面的代码使用4个字节的内存.

byte n1 = 10; // memory looks like this | 10 | 0 | 0 | 0 | 20 | 0 | 0 | 0 | 30 | 0 | 0.....
byte n2 = 20;
byte n3 = 30;
byte n4 = 40;
Run Code Online (Sandbox Code Playgroud)

这是在Visual Studio 2012 + 2010中测试的,我认为现代编译器应该为我做优化?如果放置间距真的更快,那么字节秘密地成为非功能性的int而不是它对数组不会做同样的事情,如果字节数组每个值占用4个字节就会变得更快,从而渲染整个字节的目的在32位/ 64位机器上完全无用?总结一下:为什么编译器会以这两种不同的方式分配内存,哪种方法效率低?第2部分32位/ 64位机器上的字节的实际目的是什么,如果将它存储在实际的连续字节块中是如此低效,因为VS在单独声明字节时拒绝执行.

Mit*_*tch 6

我假设这里有两个问题:

为什么编译器不将四个bytes 打包成一个Int32

局部变量通常不会针对存储进行优化,而是针对访问速度进行优化.由于在单个指令中有时无法访问单个未对齐字节的速度,并且直到最近(2009年),比对齐地址慢一个数量级,编译器作者通常使用对齐宽度作为合理的权衡.

除此之外,.Net Framework不是针对x86而是针对Common Language Infrastructure虚拟机.CLI规范必须支持最低公分母,IA64和ARM不支持非QWORD对齐内存访问.为此,CLI堆栈"只能存储最小4字节宽的值"(P.330).

他们为什么这么做?我认为潜在或实际的性能增益超过了内存使用量的增加.鉴于在任何给定范围内64个函数局部的额外限制,应该有一个强烈的愿望(超出良好的设计)以保持给定范围内的变量数量很小.因此,净开销限制为192字节,相当于我系统中使用的额外0.0000002%的内存.

请记住,如果您正在访问一个字节数组,那么您实际上存储的是一个指针 - 它是内存地址的宽度(4或8个字节)并直接访问内存.您正在管理哪个字节的语义,并采用该复杂性.

如何以紧凑的形式存储内容以最小化内存使用

正如您所指出的,如果您的数据是大量字节,请使用字节数组来避免开销.如果你的数据是不同类型的,可以使用很多类,允许用于打包数据的访问之一(BinaryReader,BinaryWriter,BitConverter,unsafe代码,struct用S StructLayout.Pack字段设置都令人难以忘怀).

如果您有大量数据,请使用具有固定布局结构的内存映射文件,以最大限度地减少内存使用,同时仍允许数据集大于计算机中的内存量.它比正常的内存访问更难吗?是的,是的 - 但优化是管理内存使用,速度和程序员劳动的平衡行为.最便宜的一个通常是记忆.

或者,花费几百美元并获得足够的内存,这无关紧要.对于大多数情况,32 GB(newegg上240美元)允许相当多的不关心.