2010-05-17 9 views
7

Empecé a trabajar con C# hace unas semanas y ahora estoy en una situación en la que necesito construir una bandera "bit set" para manejar diferentes casos en un algoritmo. Tengo, pues, dos opciones:¿Alguna mejora significativa en el rendimiento al usar operadores bit a bit en lugar de simples sumas int en C#?

enum RelativePositioning 
    { 
     LEFT = 0, 
     RIGHT = 1, 
     BOTTOM = 2, 
     TOP = 3, 
     FRONT = 4, 
     BACK = 5 
    } 

    pos = ((eye.X < minCorner.X ? 1 : 0) << (int) RelativePositioning.LEFT) 
     + ((eye.X > maxCorner.X ? 1 : 0) << (int) RelativePositioning.RIGHT) 
     + ((eye.Y < minCorner.Y ? 1 : 0) << (int) RelativePositioning.BOTTOM) 
     + ((eye.Y > maxCorner.Y ? 1 : 0) << (int) RelativePositioning.TOP) 
     + ((eye.Z < minCorner.Z ? 1 : 0) << (int) RelativePositioning.FRONT) 
     + ((eye.Z > maxCorner.Z ? 1 : 0) << (int) RelativePositioning.BACK); 

O:

enum RelativePositioning 
    { 
     LEFT = 1, 
     RIGHT = 2, 
     BOTTOM = 4, 
     TOP = 8, 
     FRONT = 16, 
     BACK = 32 
    } 

    if (eye.X < minCorner.X) { pos += (int) RelativePositioning.LEFT; } 
    if (eye.X > maxCorner.X) { pos += (int) RelativePositioning.RIGHT; } 
    if (eye.Y < minCorner.Y) { pos += (int) RelativePositioning.BOTTOM; } 
    if (eye.Y > maxCorner.Y) { pos += (int) RelativePositioning.TOP; } 
    if (eye.Z > maxCorner.Z) { pos += (int) RelativePositioning.FRONT; } 
    if (eye.Z < minCorner.Z) { pos += (int) RelativePositioning.BACK; } 

Podría haber usado algo tan ((eye.X > maxCorner.X) << 1) pero C# no lo permite la conversión implícita de bool a int y el operador ternario era lo suficientemente similares. Mi pregunta ahora es: ¿hay alguna mejora en el rendimiento al usar la primera versión en lugar de la segunda?

Gracias
Tommaso

+8

de referencia antes de realizar micro optimizaciones –

+0

De acuerdo con Mitch Wheat. También prefiere la legibilidad sobre el rendimiento, a menos que pueda probar un cuello de botella con un generador de perfiles. – OregonGhost

+4

"Deberíamos olvidarnos de pequeñas eficiencias, digamos aproximadamente el 97% del tiempo: la optimización prematura es la raíz de todo mal" Donald Knuth – Cagdas

Respuesta

5

La línea if operador (?, :) generará casi la misma IL como la lista estándar if en el segundo ejemplo. La única diferencia que verá aquí son las operaciones particulares que realizará el procesador, y puedo apostar que ADD es más rápido que SHL.
Dado que va a agregar los resultados de todos modos, optaría por el segundo ejemplo (además, hace que sea mucho más fácil de leer).

EDITAR
acabo de comprobar la IL de ambos ejemplos, y que va en contra de lo que he dicho anteriormente.
El primer ejemplo genera mucho menos IL (34 líneas menos), por lo que tendrá que ejecutar una prueba de rendimiento para determinar realmente si también es más rápido.

+0

+1 para la edición. –

0

¿Significativamente más rápido? no. ¿Un poco más rápido? Un poco.

8

Definitivamente debe utilizar el Flags attribute para su enumeración. De esa manera se vería algo así:

[Flags] 
public enum RelativePositionings 
{ 
    None = 0, 
    Left = 1, 
    Right = 2, 
    Bottom = 4, 
    Top = 8, 
    Front = 16, 
    Back = 32 
} 

Con esto se puede hacer tales cosas como:

var position = RelativePositionings.Left | RelativePositionings.Front; 

y comprobar para cada estado por:

if(position.HasFlag(RelativePositioning.Left)) 
{ 
    //To do: if left bit is set? 
} 
Cuestiones relacionadas