type sharp operator and .net memory char boolean

.net - sharp - value types and reference types



¿Por qué boolean consume más memoria que char? (9)

¿Por qué un booleano consume 4 bytes y un char 2 bytes en .NET Framework? Un booleano debería ocupar 1 bit o al menos ser más pequeño que un char.


En primer lugar, debe utilizar un generador de perfiles para determinar dónde tiene un problema de memoria, en mi humilde opinión.


Encontré esto: "En realidad, un booleano tiene 4 bytes, no 2. La razón es que eso es lo que CLR admite para Boolean. Creo que eso es lo que hace porque los valores de 32 bits son mucho más eficientes de manipular, por lo que el tiempo / espacio La compensación es, en general, vale la pena. Debe usar la clase de vector de bits (olvide dónde está) si necesita unir un montón de bits ... "

Está escrito por Paul Wick en http://geekswithblogs.net/cwilliams/archive/2005/09/18/54271.aspx


Es porque Windows y .Net han usado Unicode (UTF 16) desde el inicio como su conjunto de caracteres interno. UTF 16 utiliza 2 bytes por carácter o un par de palabras de 2 bytes por carácter, pero solo si es necesario, ya que es una codificación de ancho variable .

"Para los caracteres en el plano multilingüe básico (BMP) la codificación resultante es una sola palabra de 16 bits. Para los caracteres en los otros planos, la codificación dará como resultado un par de palabras de 16 bits"

Mi conjetura con respecto a los booleanos sería que son cuatro bytes, ya que el registro predeterminado es de 32 bits y este sería el tamaño mínimo .Net podría hacer una operación lógica de manera eficiente, a menos que se utilicen operaciones en modo bit.


Es una cuestión de alineamiento de memoria. Las variables de 4 bytes funcionan más rápido que las de 2 bytes. Esta es la razón por la que debe usar int en lugar de byte o short para contadores y similares.

Debe usar variables de 2 bytes solo cuando la memoria es una preocupación mayor que la velocidad. Y esta es la razón por la cual char (que es Unicode en .NET) toma dos bytes en lugar de cuatro.


Esto se debe a que en un entorno de 32 bits, la CPU puede manejar valores de 32 bits más rápido que los valores de 8 bits o 16 bits, por lo que esta es una compensación de velocidad / tamaño. Si tiene que guardar memoria y tiene una gran cantidad de bools, solo use uint y guarde sus booleanos como los bits de 4 bytes byint . Los caracteres tienen 2 bytes de ancho, ya que almacenan caracteres Unicode de 16 bits.


Independientemente de la menor diferencia en el almacenamiento de la memoria, usar Boolean para valores verdaderos / falsos sí / no es importante para los desarrolladores (incluido usted mismo, cuando debe volver a visitar el código un año después), ya que refleja con mayor precisión su intención. Hacer que el código sea más comprensible es mucho más importante que guardar dos bytes.

Hacer que su código refleje con mayor precisión su intención también reduce la probabilidad de que alguna optimización del compilador tenga un efecto negativo. Este consejo trasciende plataformas y compiladores.


La memoria solo es una preocupación si tiene una gran cantidad de bits, en cuyo caso puede usar la clase System.Collections.BitArray.


También debería usar boolean para ayudar a escribir el código que se puede mantener. Si estoy mirando el código viendo que algo es un booleano es más que vale la pena ahorrar en la memoria para descubrir que estás usando char como booleanos.


Acerca de boolean

La mayoría de las otras respuestas funcionan mal: la alineación y la velocidad es la razón por la cual un programador debe apegarse a int para los contadores de bucle, no por qué el compilador puede hacer que un byte tenga 4 bytes de ancho. Todos sus razonamientos, de hecho, se aplican a byte y short así como a boolean.

En C # como mínimo, bool (o System.Boolean) es una estructura incorporada de 1 byte de ancho, que puede encasillarse automáticamente, por lo que tiene un objeto (que necesita dos palabras de memoria para representarse, como mínimo, es decir, 8 / 16 bytes en entornos de 32/64 bits, respectivamente) con un campo (al menos un byte) más una palabra de memoria para señalarlo, es decir, en total al menos 13/25 bytes.

Esa es de hecho la primera entrada de Google en "tipos primitivos de C #". http://msdn.microsoft.com/en-us/library/ms228360(VS.80).aspx

También el enlace citado ( http://geekswithblogs.net/cwilliams/archive/2005/09/18/54271.aspx ) también establece que un booleano, según el estándar CLI, toma 1 byte.

En realidad, sin embargo, el único lugar donde esto es visible está en las matrices de booleanos, n booleanos tomarían n bytes. En los otros casos, un booleano puede tomar 4 bytes.

  • Dentro de una estructura, la mayoría de los tiempos de ejecución (también en Java) alinearían todos los campos a un límite de 4 bytes para el rendimiento. El Monty JVM para dispositivos integrados es más inteligente, supongo que reordena los campos de manera óptima.
    • En la pila de marco / operando local para el intérprete, en la mayoría de las implementaciones, para el rendimiento, una entrada de pila es una palabra de memoria (y tal vez en .NET debe ser de 64 bits de ancho para admitir doble y larga, que en .NET usa solo 1 entrada de pila en lugar de 2 en Java). Un compilador JIT en su lugar puede usar 1 byte para locales booleanos mientras mantiene alineados otros vars reordenando campos sin impacto en el rendimiento, si la sobrecarga adicional lo vale.

Acerca de char

char son dos bytes porque cuando se requiere soporte para la internacionalización, el uso de caracteres de dos bytes internamente es la apuesta más segura. Esto no está relacionado directamente con elegir apoyar Unicode, sino con la opción de apegarse a UTF-16 y al Plano multilingüe básico. En Java y C #, puede suponer todo el tiempo que un carácter lógico encaja en una variable de tipo char.