为什么.NET中的布尔值为4字节?

为什么.NET中的布尔值为4字节?,.net,.net,为什么System.Boolean需要4个字节?它只存储一个状态,无论是真是假,可以存储在少于4字节的空间中。谷歌搜索的第一个结果告诉我,这与内存对齐有关。推送一个四字节的Int32比处理单个字节/位要快。因为它很快 32位处理器通常使用32位值。使用较小的值需要较长的指令或额外的逻辑。我认为这只是为了性能,32位值的操作效率更高。你从哪里得到的?System.Boolean只接受1字节 试试看: Console.WriteLine( sizeof( System.Boolean ).ToStr

为什么System.Boolean需要4个字节?它只存储一个状态,无论是真是假,可以存储在少于4字节的空间中。

谷歌搜索的第一个结果告诉我,这与内存对齐有关。推送一个四字节的Int32比处理单个字节/位要快。

因为它很快


32位处理器通常使用32位值。使用较小的值需要较长的指令或额外的逻辑。

我认为这只是为了性能,32位值的操作效率更高。

你从哪里得到的?System.Boolean只接受1字节

试试看:

Console.WriteLine( sizeof( System.Boolean ).ToString() );

实际上,
bool
仅为1个字节,但对齐可能会导致在32位平台上使用4个字节,甚至在64位平台上使用8个字节。例如,
Nullable
(又称
bool?
)类型根据平台使用完整的32位或64位,即使它仅由两个
bool
组成编辑:正如Jon Skeet所指出的,对齐的填充并不总是存在。例如,
Nullable
s的数组每个对象只需要2个字节,而不是4或8个字节


但是,如果要存储很多位,那么即使是表示
bool
的8位也可能被认为是浪费。因此,如果您创建了一个具有许多<代码> BoOL s的成员,(或者使用许多<代码>可空< /COD>类型),<强>和您的类的用户可能会创建许多实例,您可以改为使用<代码> BITVECCTROR2。例如,框架本身使用这种技术来减少许多Windows窗体控件的内存占用。

我使用以下代码创建了几个数组并对它们进行了测试。浮点?[100000]使用的内存是浮点[100000]的两倍。这是因为浮点数中伴随浮点数的布尔?大小写对齐到32位(至少在我的机器上;-))


在封送类型后检查大小:Console.Write(System.Runtime.InteropServices.Marshal.SizeOf(new System.Boolean());这是你不应该做的。大多数非托管API对BOOL值使用int,Marhsal.SizeOf()告诉您非托管类型的大小。封送BOOL要比这复杂得多。我写了一篇关于这个主题的博文,涵盖了各种大小:我使用GC.GetTotalMemory来检查它。。。我的帖子太长,无法放在这里的回复中,但我添加了它作为对这个问题的回答,以供感兴趣的人使用。即使是Nullable在某些情况下也只会使用两个字节,例如,如果你有一个数组的话。是的,你是对的。我本以为它会为了性能而对齐数组索引,但它似乎没有。这是C标准库和编译器的产物。在32位和64位平台上,内存不是真正的问题,大多数编译器都会针对性能而不是代码大小进行优化。编译器不会将布尔值打包到位字段中,除非在结构中显式完成。这是为了在传递指针时保持足够的性能,否则你不仅要取消引用,还要屏蔽每次访问。由于问题已存档,请以后再添加特定链接。我没有使用谷歌搜索的唯一原因是它将我引用到同一个stackoverflow页面;)
long startMem = 0, stopMem = 0;
DateTime startTime = DateTime.Now;
private void StartMemoryUsage()
{
    GC.Collect();
    GC.Collect();
    startMem = GC.GetTotalMemory(true);
    startTime = DateTime.Now;
}
private void StopMemoryUsage()
{
    GC.Collect();
    GC.Collect();
    stopMem = GC.GetTotalMemory(true);

    Console.WriteLine("---> {0} sec.  Using {1} KB.", (DateTime.Now - startTime).TotalSeconds, ((stopMem - startMem) / 1000).ToString());
}