Pregunta

¿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.

¿Fue útil?

Solución

Es una cuestión de alineación 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.

Otros consejos

Acerca de boolean

La mayoría de las otras respuestas se equivocan: 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.

Al menos en C #, bool (o System.Boolean) es una estructura integrada de 1 byte de ancho, que se puede encuadrar 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 "C # tipos primitivos". 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 es en 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 sabio, supongo que reordena los campos de manera óptima.
    • En la pila de trama / operando local para el intérprete, en la mayoría de las implementaciones, para el rendimiento, una entrada de pila tiene una palabra de memoria (y tal vez en .NET debe tener 64 bits de ancho para admitir doble y largo, lo que en .NET usa solo 1 entrada de pila en lugar de 2 en Java). Un compilador JIT puede usar 1 byte para locales booleanos mientras mantiene otros vars alineados 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 interno de caracteres de dos bytes es la apuesta más segura. Esto no está relacionado directamente con la elección de soportar Unicode, sino con la opción de adherirse 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 carácter.

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 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, simplemente use uint sy guarde sus booleanos como bits de 4 byte uint s. Los caracteres tienen 2 bytes de ancho ya que almacenan caracteres Unicode de 16 bits.

Independientemente de la pequeña diferencia en el almacenamiento de memoria, usar Boolean para valores verdadero / falso sí / no es importante para los desarrolladores (incluido usted mismo, cuando tiene que volver a visitar el código un año después), ya que refleja con mayor precisión su intención. Hacer que su 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.

También debe usar boolean para ayudar a escribir código mantenible. Si estoy mirando el código y veo que algo es un booleano, vale la pena el ahorro de memoria para descubrir que estás usando char como booleanos.

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

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

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

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

Es porque Windows y .Net han utilizado Unicode (UTF 16) desde el inicio como su conjunto de caracteres interno. UTF 16 usa 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 Bilingüe Multilingüe (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 suposición 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 realizar una operación lógica de manera eficiente, a menos que use operaciones bit a bit.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top