为什么布尔值比char消耗更多的内存?

时间:2008-10-15 10:26:55

标签: .net memory char boolean

为什么布尔在.NET框架中消耗4个字节和2个字节?布尔值应占用1位或至少小于char。

9 个答案:

答案 0 :(得分:50)

这是一个记忆对齐的问题。 4字节变量的工作速度比2字节变量快。这就是为什么你应该使用int而不是字节或短路用于计数器等。

只有当内存比速度更重要时,才应使用2字节变量。这就是为什么char(在.NET中是Unicode)占用两个字节而不是四个字节的原因。

答案 1 :(得分:16)

关于boolean

大多数其他答案都错了 - 对齐和速度是程序员应该坚持使用int for循环计数器的原因,而不是为什么编译器可以使一个字节为4字节宽。事实上,所有的推理都适用于字节和短路以及布尔值。

至少在C#中,bool(或System.Boolean)是一个1字节宽的内置结构,可以自动装箱,所以你有一个对象(至少需要两个记忆词来表示)即分别在32/64位环境下的8/16字节),其中一个字段(至少一个字节)加上一个指向它的存储器字,即总共至少13/25字节。

这确实是“C#原型”的第一个Google条目。 http://msdn.microsoft.com/en-us/library/ms228360(VS.80).aspx

此外,引用的链接(http://geekswithblogs.net/cwilliams/archive/2005/09/18/54271.aspx)还指出,CLI标准的布尔值占用1个字节。

然而,实际上,唯一可以看到它的地方是布尔数组 - 布尔值将占用n个字节。在其他情况下,一个布尔值可能需要4个字节。

  • 在结构内部,大多数运行时(也在Java中)会将所有字段对齐到4字节边界以提高性能。用于嵌入式设备的Monty JVM更明智 - 我想它可以最佳地重新排序字段。
    • 在解释器的本地帧/操作数堆栈上,在大多数实现中,为了提高性能,一个堆栈条目是一个内存字宽(并且在.NET上它必须是64位宽才能支持double和long,在.NET上只使用1个堆栈条目而不是Java中的2个。 JIT编译器可以使用1个字节作为布尔本地,同时通过重新排序字段来保持其他变量对齐,而不会影响性能,如果额外的开销是值得的。

关于char

char是两个字节,因为当需要支持国际化时,在内部使用双字节字符是最安全的选择。这与选择支持Unicode无关,而是与坚持UTF-16和基本多语言平面的选择无关。在Java和C#中,您可以假设一个逻辑字符串适合char类型的变量。

答案 2 :(得分:8)

这是因为在32位环境中,CPU可以比8位或16位值更快地处理32位值,因此这是速度/大小权衡。如果你必须节省内存并且你有大量的bool,只需使用 uint 并将你的布尔值保存为4字节 uint 的位。 字符宽度为2个字节,因为它们存储16位Unicode字符。

答案 3 :(得分:3)

无论内存存储的细微差别如何,对于开发人员(包括您自己,一年后必须重新访问代码时)使用布尔值来表示真/假是/否值非常重要,因为它更准确地反映了您的意图。让代码更容易理解比保存两个字节重要得多。

使您的代码更准确地反映您的意图也降低了某些编译器优化会产生负面影响的可能性。这个建议超越了平台和编译器。

答案 4 :(得分:2)

您还应该使用布尔值来帮助编写可维护的代码。如果我看一下代码,看到某个东西是一个布尔值就更值得节省内存,以确定你使用char作为布尔值。

答案 5 :(得分:1)

我发现:“实际上,布尔值是4个字节,而不是2.原因是这就是CLR支持的布尔值。我认为这就是它的作用,因为32位值的操作效率要高得多,所以时间/空间权衡一般来说是值得的。你应该使用位向量类(忘记它在哪里)如果你需要将一堆位一起堵塞......“

由Paul Wick在http://geekswithblogs.net/cwilliams/archive/2005/09/18/54271.aspx

撰写

答案 6 :(得分:1)

如果您有大量的位,则只关注内存,在这种情况下,您可以使用System.Collections.BitArray类。

答案 7 :(得分:1)

首先,您应该使用分析器来确定您在哪里遇到内存问题,恕我直言。

答案 8 :(得分:0)

因为Windows和.Net从一开始就使用Unicode (UTF 16)作为内部字符集。 UTF 16每个字符使用2个字节或每个字符使用一对2字节字,但仅在需要时使用,因为它是variable width encoding

“对于基本多语言平面(BMP)中的字符,结果编码是一个16位字。对于其他平面中的字符,编码将产生一对16位字”

我对布尔值的猜测是它们是四个字节,因为默认寄存器是32位,这将是最小大小.Net可以有效地进行逻辑运算,除非使用按位运算。