2011-09-10 9 views
7

Estoy haciendo un juego en el que estoy almacenando una gran cantidad de datos en un entero o largo, porque tendré una enorme cantidad de datos. No quiero utilizar clases completas por motivos de rendimiento, y no son necesarias. Encontré dos métodos para recuperar un bit de un entero. Me preguntaba si alguien sabe cuál debería usar o cuál es más rápido.¿Qué algoritmo es más rápido para verificar si se establece un bit?

Los métodos:

return (integer & (1 << bit)) != 0;

return (integer >> bit& 0x1) == 1;

+23

optimización prematura es el juguete de los diablos – austinbv

+4

micro-punto de referencia perfecto para que usted pruebe. Ejecuta ambos en un bucle de 1 millón y mide el tiempo. – Oded

+0

Estoy casi completamente seguro de que el segundo es simplemente "borracho", independientemente de si es más rápido o no ... – bdonlan

Respuesta

16

Las posibilidades son que la parte que está probando es "más constante" que la que está probando. Por lo tanto, puede hacer constantes para el bit, lo que significa que solo tiene que hacer el cambio una vez. Por ejemplo:

static final int LEFT_WALL = 1 << 1; 
static final int RIGHT_WALL = 1 << 2; 
static final int BOTTOM_WALL = 1 << 3; 
static final int TOP_WALL = 1 << 4; 

Luego, en su bucle, estas a comprobar

if ((integer & LEFT_WALL) != 0) 
    // left wall collision 
if ((integer & RIGHT_WALL) != 0) 
    // right wall collision 
... 

Por lo que sólo está haciendo dos operaciones (AND bit a bit y comparar) en el bucle, no tres (desplazamiento, Y y comparar).

Y lo más importante (como se señala en los comentarios) que la ganancia de velocidad, también deja mucho más claro para qué está utilizando cada bit, por lo que el código es más fácil de leer.

+6

Aún mejor que guardar una operación, puedo leerla y encontrarle sentido fácilmente. – tvanfosson

+0

idea impresionante. tengo casi los mismos vars finales en mi programa también XD. Por cierto, la mayoría de la gente está diciendo que esto no es una opción muy importante, pero en ciertos momentos tendré que ejecutar esto unas 24 millones de veces, lol –

+1

@stas Sí, y ahorrará un turno de esa manera, lo que probablemente con μop fusion y costos de co Probablemente la mitad de un ciclo. Por lo tanto, ejecutar esto 24 * 10^6 veces le ahorra aproximadamente 12 millones de ciclos o aproximadamente 4 ms en una CPU de 3 ghz. Grandes ahorros que. – Voo

5

Esto depende de la implementación y depende de su hardware y compilador. Sin ejecutar realmente pruebas de tiempo, no creo que nadie pueda decir cuál será mejor.

Además, no me preocuparía algo así a menos que tenga evidencia tangible de que este código es tan crítico en el tiempo que debe optimizarlo. Dedicar tiempo al código de microoptimización de este tipo no es probable que sea productivo a menos que sepa que es un cuello de botella de rendimiento, y me sorprendería enormemente que no pudiera obtener aún más rendimiento de bonificación optimizando otras partes del código. Intente crear un perfil del código para ver cuáles son los cuellos de botella reales, luego vaya a optimizar esas partes.

3

Es casi seguro que no hay diferencia.

Pero la única manera de estar seguro, para su plataforma, es perfilarlos a ambos. Sin embargo, necesitará medir el tiempo de un gran número en un bucle (como 100e6), para minimizar el error de medición.

Cuestiones relacionadas