2010-10-28 17 views
17

considerar los siguientes escenarios: 2Que cuesta más mientras se repite; asignación o una declaración if?

boolean b = false; 
int i = 0; 
while(i++ < 5) { 
    b = true; 
} 

O

boolean b = false; 
int i = 0; 
while(i++ < 5) { 
    if(!b) { 
     b = true; 
    } 
} 

¿Qué es más "costosa" que hacer? Si la respuesta depende del lenguaje/compilador utilizado, proporcione. Mi lenguaje de programación principal es Java.

Por favor, no hagas preguntas como por qué querría hacer ninguna de las dos ... Son solo ejemplos básicos que señalan lo relevante: si una variable debe establecer el mismo valor en un bucle una y otra vez o debería ser probado en cada ciclo que tiene un valor necesario para cambiar?

+2

posible duplicado de [Are If Thens más rápido que la multiplicación y la asignación?] (Http://stackoverflow.com/questions/4024201/are-if-thens-faster-then-multiplication-and-assignment) –

+0

Si mal no recuerdo mi clase de compilador correctamente, debido a http://en.wikipedia.org/wiki/Branch_predictor, ambos serán más o menos lo mismo. Creo que la primera vez tomaría un poco más de tiempo para hacer la rama, pero después de eso el compilador puede hacer predicciones y ajustarlas en consecuencia. –

+0

Aquí encontrarás muchas respuestas http://www.agner.org/optimize/optimizing_cpp.pdf – ruslik

Respuesta

1

¿Está tratando de averiguar si al hacer la asignación cada bucle es más rápido en tiempo de ejecución total que haciendo una comprobación en cada bucle y solo asignando una al satisfacer la condición de prueba?

En el ejemplo anterior supongo que el primero es más rápido. Realiza 5 asignaciones. En este último realizas 5 pruebas y luego una tarea.

Pero tendrá que aumentar el recuento de iteraciones y agregar algunos temporizadores de cronómetro para estar seguro.

0

Cualquier compilador (excepto, quizás, en la depuración) optimizará estas dos declaraciones a

bool b = true; 

Pero, en general, la velocidad relativa de la asignación y la rama dependerá de la arquitectura del procesador, y no en el compilador. Un procesador moderno y súper escalar funciona de manera horrible en las ramas. Un microcontrolador simple usa aproximadamente el mismo número de ciclos por cada instrucción.

0

relativa a su ejemplo barebones (y tal vez su aplicación real):

boolean b = false; 
// .. other stuff, might change b 
int i = 0; 
// .. other stuff, might change i 
b |= i < 5; 
while(i++ < 5) { 
    // .. stuff with i, possibly stuff with b, but no assignment to b 
} 

problema resuelto?

Pero realmente - va a ser una cuestión del costo de su prueba (generalmente más que solo if (boolean)) y el costo de su asignación (generalmente más que primitive = x). Si la prueba/asignación es costosa o su ciclo es lo suficientemente largo o si tiene demandas de rendimiento lo suficientemente altas, es posible que desee dividirlo en dos partes, pero todos estos criterios requieren que pruebe cómo funcionan las cosas. Por supuesto, si sus requisitos son más exigentes (por ejemplo, b puede cambiar de dirección), es posible que necesite una solución más compleja.

3

¿Has probado este? Al trabajar en un sistema Linux, puse su primer ejemplo en un archivo llamado LoopTestNoIf.java y su segundo en un archivo llamado LoopTestWithIf.java, envolví una función principal y una clase alrededor de cada uno de ellos, compilé y luego ejecuté este script bash:

#!/bin/bash 
function run_test { 
    iter=0 
    while [ $iter -lt 100 ] 
    do 
    java $1 
    let iter=iter+1 
    done 
} 
time run_test LoopTestNoIf 
time run_test LoopTestWithIf 

los resultados fueron los siguientes:

real 0m10.358s 
user 0m4.349s 
sys  0m1.159s 

real 0m10.339s 
user 0m4.299s 
sys  0m1.178s 

Mostrando que el tener la ligera si lo hace más rápido en mi sistema.

+0

Obtuve resultados similares, por favor mira mi comentario a Andy Lester. – heikkim

27

No olvides el rules of Optimization Club.

  1. La primera regla del Club de optimización es que usted no optimiza.
  2. La segunda regla de Optimization Club es que no se optimiza sin medir.
  3. Si su aplicación se ejecuta más rápido que el protocolo de transporte subyacente, la optimización ha terminado.
  4. Un factor a la vez.
  5. No marketroids, no marketroid horarios.
  6. Las pruebas continuarán tanto como sea necesario.
  7. Si esta es su primera noche en el Optimization Club, tiene que escribir un caso de prueba.

Parece que ha infringido la regla 2. No tiene medida. Si realmente quiere saber, responderá la pregunta usted mismo configurando una prueba que ejecute el escenario A contra el escenario B y encuentre la respuesta. Hay tantas diferencias entre diferentes entornos que no podemos responder.

+0

No estaba optimizando. Mi motivación fue la curiosidad. Acepto su respuesta: "Hay tantas diferencias entre diferentes entornos que no podemos responder". – heikkim

+0

Probé esto en Java haciendo un bucle de 100 000 veces y parece que una asignación condicionada es ligeramente más rápida cuando la prueba es bastante simple. – heikkim

Cuestiones relacionadas