2009-03-15 10 views
24

Si tiene una enumeración en su aplicación y solo tiene algunos elementos, ¿debería forzar al tipo subyacente a ser el tipo más pequeño posible?Al declarar una enumeración, ¿debe forzar el tipo a byte para menos de 256 entidades?

enum smaller : byte 
    { 
     one, 
     two, 
     three 
    }; 
+2

Para que quede claro, yo estaba hablando de las mejores prácticas en lugar de optimización, aunque esta cuestión se presentó como una cuestión de optimización. Mi punto era realmente ya que se puede specifiy que, en caso de que "siempre" o en caso de que especifique o dejar que el compilador de decidir? – ghost

Respuesta

32

No. No optimizar prematuramente menos que has demostrado con un perfilador que en realidad es un problema.

+0

Creo que .NET está optimizado para que los Enteros sean de todos modos. – Ray

+1

Para ser claros, estaba hablando de las mejores prácticas en lugar de la optimización, aunque esta pregunta surgió como una pregunta de optimización. Mi punto era realmente ya que se puede specifiy que, en caso de que "siempre" o en caso de que especifique o dejar que el compilador de decidir? Supongo que dejar como funciona para ambos. – ghost

+2

¿cómo demostrarías con un generador de perfiles si byte o int es más eficiente? –

1

¿Qué ganarías? Ahorrarías 3 bytes de memoria, a costa de una ejecución un poco más lenta y un código menos intuitivo o legible. (Al leer esto, me pregunto si realmente tenía una razón para convertirlo en byte, y cuál podría haber sido esa razón. Presumiblemente, hizo un esfuerzo por utilizar un tipo no predeterminado por algún motivo).

Si va a almacenar millones de estas cosas, entonces sí, ahorrando unos pocos bytes en cada uno puede dar sus frutos. De otra manera no.

Es la misma razón por la que normalmente no utiliza bytes o cortos en lugar de int.

0

No debe asignar un cierto tipo entero a las enumeraciones, pero deje que el entorno .NET encuentre el mejor "tamaño" para la enumeración. Como dijo JaredPar, si cambias el tipo de datos, definitivamente debería comprobar si realmente ayuda.

El hecho es que los enteros de 32 bits son "naturales" en los procesadores x86 porque se pueden alinear fácilmente de una manera óptima.

26

En relación con las mejores prácticas:

Cuando usted no tiene una razón particular para hacer la enumeración de un byte de tipo, debe dejarlo como predeterminado.

Cada vez que utilice una enumeración en una instrucción switch debe tener una cláusula "predeterminada" para un valor enum no válido. Por lo tanto, no importa si está buscando 256-NumRealEnumValues ​​o 2^32-NumRealEnumValues. Ambos tendrán una cláusula predeterminada que maneja todos los casos inválidos.

Una razón para establecer explícitamente el tipo de la enumeración, es si desea que su enumeración se corresponda con otro tipo en su programa y necesita emitir explícitamente entre ellos.

Cambiar el tipo al ajuste más pequeño no le ayudará tampoco con los problemas de versión. A menos que tenga exactamente el tamaño máximo de la enumeración completada. Al hacer una versión de los problemas me refiero a cuando tienes un dll compilado usando la enumeración, entonces agregas un nuevo valor enum, se puede ejecutar algún código que no estaba destinado a entrar en la cláusula "por defecto" de una instrucción switch.

relacionadas con la eficiencia:

No hay ningún beneficio en términos de eficiencia para que sea un byte.

int es más eficiente de usar porque la CPU en x86 tiene registros de 32 bits. La copia en un registro se hace 32 bits a la vez.

Cuando utiliza un tipo más pequeño, tiene que poner a cero parte del registro y copiar en el resto de los bits de orden inferior del registro.

+3

. Está pensando solo en el rendimiento de la CPU. Si bien el costo de poner a cero los bits de registro requeridos es bastante insignificante, las ganancias de eficiencia en el uso de la memoria pueden ser considerables. – 0b101010

+1

"puede ser sustancial" es técnicamente cierto, pero dudo que resulte sustancial con mucha frecuencia.En mi experiencia, los bytes individuales (no en matrices) a menudo se rellenan con un límite de palabras, por lo que muchos bytes ocupan la misma cantidad de memoria que un int. – Luke

5

La única razón para hacer esto es si está almacenando o transmitir este valor utilizando un protocolo definido que exige el campo para ser de ese tamaño.

+3

No diría que esa es la única razón. A menudo hago esto porque necesito mantener cien millones o más elementos en la memoria, y los tres bytes por ahorro de registros son bastante significativos. –

+0

@Jim: si tiene tantos elementos en la memoria, es más probable que tenga un problema en otro lugar. Estás sacrificando el rendimiento por el espacio. Debería intercambiar esos elementos de la memoria u obtener más memoria. – Juliano

+3

@Juliano No creo que sea indicativo de un problema en otro lado. En el mundo de las operaciones algorítmicas en tiempo real, a menudo necesita guardar millones de elementos de datos (por ejemplo, transacciones, actualizaciones de libros de pedidos) en la memoria a la vez. Reducir 3 bytes por elemento de datos produce un beneficio significativo. – 0b101010

0

Si está correlacionando con el modelo de enumeración a otro modelo, o la serialización, o su enumeración se refleja en la columna de la base de datos - entonces sugeriría que especifique el tipo de forma explícita.


Escenario: tiene una columna en la base de datos: status_id con el tipo tinyint. Y tiene enumeración en su código: enum Status { Well = 1, Bad = 2 }. Y usas esta enumeración en alguna entidad. Digamos que usas los frameworks de la entidad core 2.0. Si intenta leer/escribir esta entidad desde la base de datos, obtendrá el error "No se puede lanzar el objeto", a menos que especifique explícitamente el tipo byte.

Cuestiones relacionadas