Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 为什么布尔值比字符消耗更多内存?_.net_Memory_Char_Boolean - Fatal编程技术网

.net 为什么布尔值比字符消耗更多内存?

.net 为什么布尔值比字符消耗更多内存?,.net,memory,char,boolean,.net,Memory,Char,Boolean,为什么在.NET framework中,布尔值消耗4个字节,字符消耗2个字节?布尔值应占1位或至少小于字符。这是内存对齐的问题。4字节变量比2字节变量工作得更快。这就是为什么应该使用int而不是byte或short来表示计数器等 只有当内存比速度更重要时,才应该使用2字节变量。这就是为什么char(在.NET中是Unicode)需要两个字节而不是四个字节的原因。我发现:实际上,布尔值是4字节,而不是2字节。原因是CLR支持布尔型。我认为它就是这样做的,因为32位的值更容易操作,所以时间/空间的折

为什么在.NET framework中,布尔值消耗4个字节,字符消耗2个字节?布尔值应占1位或至少小于字符。

这是内存对齐的问题。4字节变量比2字节变量工作得更快。这就是为什么应该使用int而不是byte或short来表示计数器等

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

我发现:实际上,布尔值是4字节,而不是2字节。原因是CLR支持布尔型。我认为它就是这样做的,因为32位的值更容易操作,所以时间/空间的折衷通常是值得的。如果需要将一组位组合在一起,则应使用位向量类(忘记它在哪里)。”


这是Paul Wick在

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

只有当您有一个大的位数组时,内存才是一个问题,在这种情况下,您可以使用System.Collections.BitArray类。

首先,您应该使用探查器来确定内存问题出在哪里,IMHO。

这是因为Windows和.Net从那时起就一直在使用它初始值作为其内部字符集。每个字符使用2字节或每个字符使用一对2字节的字,但仅在需要时使用,因为它是一个字符集

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


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

关于
布尔运算

大多数其他的答案都是错误的——对齐和速度是为什么程序员应该坚持使用int来表示循环计数器,而不是为什么编译器可以将一个字节设置为4字节宽。事实上,你所有的理由都适用于byte和short以及boolean

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

这确实是谷歌在“C#primitive types”上的第一个条目。

此外,引用的链接()还指出,按照CLI标准,布尔值需要1个字节

然而,实际上,唯一可见的地方是布尔数组,n个布尔值需要n个字节,在其他情况下,一个布尔值可能需要4个字节

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


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

您还应该使用boolean来帮助编写可维护的代码。如果我浏览代码,发现某个东西是boolean,则更值得节省内存,以确定您使用char作为boolean。

无论内存存储中的微小差异,使用boolean表示真/假yes/no值对于开发人员(包括您自己,当您一年后必须重新访问代码时)来说,s是很重要的,因为它更准确地反映了您的意图。使您的代码更易于理解比节省两个字节重要得多


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

我也问过自己同样的问题。出于好奇,一个结构中的两个布尔值占去了多少空间?您期望的布尔值是多少?N通常情况下,valuetypes只会被堆栈使用,因此除非您处理大量bool(如字符串),否则我不会担心。如果您有大量二进制值,请使用System.Collections.BitArray。您查看的是装箱bool的大小,而不是真实bool的大小(有关详细信息,请参阅我的答案)!您选择的答案是错误的。您通常无法使用标准体系结构引用单个内存位,这样做会非常低效。字节通常是最小的可寻址单元,在这种情况下,将考虑一个字符,即2个字节。未装箱的布尔值取1个字节-请参见下文;这根本不是对que的有效答案stions.Huh!.NET应该停止为我们做决定。@Vulcan Earge:这是个笑话,对吧?整个.NET的重点是它为我们做了很多决定(l