2010-12-02 32 views
11

Además de la legibilidad del código, ¿por qué es malo utilizar muchas sentencias if?Desventajas del uso de muchas sentencias if

+0

La mayoría de los programas tienen muchas sentencias if. Nunca escuché que esto es malo. ¿Quizás te estás refiriendo a * declaraciones profundamente anidadas * if-statements? –

+1

No lo sé, ¿verdad? ¿En que contexto? –

+0

Un problema es que está introduciendo muchas rutas de código. Esto hace que sea difícil probar el código. Puede ser difícil desencadenar cada ruta por separado. Es mejor encontrar patrones de diseño utilizables, como la estrategia mencionada. Eso le permitiría probar mucho más fácilmente cada ruta de código individual. –

Respuesta

11

Si tiene muchas sentencias if una después de la otra, entonces una sentencia de mayúsculas y minúsculas es más útil. Al menos tiene un tiempo de respuesta fijo para cada inupt posible, ya que no necesita pasar por todas las sentencias if.

Una gran cantidad de si (y más) declaración general indica

a) Violation of Single responsibility Principle

b) deberás volver a cabo en Strategy Design Pattern

+5

Una instrucción 'switch' no necesariamente tiene un tiempo de respuesta fijo (al menos no en C#). Habiendo dicho eso, preocuparse por este tipo de ultramicro-optimizaciones es una pérdida de tiempo para casi todo el mundo. – LukeH

+2

@LukeH: De hecho, pasé la mayor parte de ayer investigando las penalizaciones de rama en mi aplicación y eliminándolas o reemplazándolas con algoritmos sin sucursales, con el fin de reducir un enganche de 250 ms a 50 ms. – Crashworks

+0

@Crashworks: Por eso dije * "casi todo el mundo" * en lugar de solo una manta * "todos" *. Sospecho que eres una de las excepciones que demuestra la regla. – LukeH

0
if(A) 
{ 
}else 
if(B) 
{ 
}else 
if(C) 
{ 
}else 
if(D) 
{ 
}else 
{ } 

Todos if s todavía tendrán que conseguir "calculado" por lo que es algo así como "O (n)". Debe evitarse cuando sea posible y usar switch(Lalala)

+1

si está usando 'else', luego' si '' s después de una condición coincidente no se evalúan. Es peor si solo no coincide 'if 'y se ejecuta el último' else'. – TheVillageIdiot

+0

@TheVillage, sí, esto es a lo que me refiero. El valor predeterminado: caso en el interruptor. p.ej. si C fuera la condición correspondiente, entonces A y B todavía tendrían que ser evaluados. pero con el interruptor podríamos "saltar" directamente a C. – Muggen

+0

@Henk, lo siento, soy solo un estudiante. – Muggen

1

A veces debido a la arquitectura del procesador, es más eficiente para encontrar una forma de evitar la ramificación en absoluto; esto podría considerarse una desventaja de las declaraciones if.

0

Otra posibilidad: depende de lo que estén haciendo las declaraciones if. En algunos casos, pueden tomar decisiones que se logran mejor mediante una jerarquía de clases diseñada adecuadamente.

¿Puede publicar algunos ejemplos de si las declaraciones que le han dicho son malas?

13

Cada if/else que escribe aumenta la cantidad de rutas de código que debe probar.

0

Si la instrucción puede producir un bloqueo en la canalización. Puede leer sobre Peligros de oleoductos here. Por lo tanto, para aplicaciones de rendimiento muy crítico, no es una buena idea tener muchas sentencias if en un gran ciclo. Consulte también el artículo this sobre predicción de bifurcación en procesadores modernos, y puntos de referencia de varias condiciones si.

Además, veo a mucha gente hablar sobre la declaración del caso. Compruebe this SO hilo.

Y para el final, wiki article sobre la tubería que probablemente todos los programadores deberían haber leído.

Espero que ayude.

1

Chusdad tiene razón. La estructura del interruptor es mejor que la del if-else múltiple. El siguiente enfoque es usar enum como una tecla de cambio. En este caso, recibirá una advertencia si olvidó mencionar uno de los elementos enum en su interruptor.

Pero si está utilizando enum y switch, avance para un mejor diseño: ¡elimine el conmutador en absoluto!

Declare el método de negocio abstracto en su enumeración. Implementarlo para cada elemento enum. La llamada enumElement.theMethod() en lugar de implementar el modificador.

Aquí hay un ejemplo.

enum Foo { 
    ONE { 
     public void foo() { 
      // do something 
     } 
    }, 

    TWO { 
     public void foo() { 
      // do something 
     } 
    }, 

    ; 
    public abstract void foo(); 
} 

Este es el código que utiliza esta:

Foo.valueOf(System.getProperty("foo")).foo(); 

comparar esta línea con lo siguiente:

String foo = System.getProperty("foo"); 
    if("ONE".equals(foo)) { 
     //..... 
    } else if("ONE".equals(foo)) { 
     //..... 
    } else { 
     //..... 
    } 

Creo que no se requieren comentarios.

3

Bueno, la pregunta que tengo que hacer es "¿en contraposición a qué?"

Si se refiere a una declaración de cambio, entonces, además de la legibilidad, puede a veces ser más eficiente. Por regla general (ciertamente en C#, probablemente en los demás) debajo de un cierto número de ramas, se convertirá en una serie de declaraciones if cuando se compilan, pero más allá de ese número se convertirá en una búsqueda basada en hash y salto que es es probable que sea más rápido en el caso promedio.

Como alternativa, si tiene un buen conocimiento de la frecuencia relativa de casos diferentes, puede ser más eficiente con un conjunto de sentencias if. P.ej. si el 95% de los casos coinciden con la primera rama, el 4% coincide con la segunda y el 1% con todos los demás, esto puede proporcionar un mejor rendimiento para el 95% de los casos al hacer una comparación única y tal vez ni siquiera la bifurcación en ese caso.

So. Tal vez hay una ganancia de eficiencia en este caso.

Aún así, la legibilidad cuenta mucho. Como un ejemplo extremo, hay un lenguaje completo de Turing que fue diseñado solo para ver cuán pequeño podría ser un compilador para un lenguaje completo de Turing. Es el diseñador llamado el idioma "brainf ** k". Esto en sí mismo es un gran comentario sobre la importancia del código legible en la programación real.

Ahora, un problema mayor con una gran cantidad de sentencias if, es que a menudo indica que está modelando algo a través de esas sentencias if que podrían modelarse mejor con una jerarquía de clases. De alguna manera, esto es solo otra lectura de la legibilidad (asumiendo que el programa funciona de cualquier manera). Sin embargo, se trata de la legibilidad y comprensibilidad del programa en general. Impactará masivamente sobre el modelo mental que tiene del programa, la extensibilidad y el efecto, no solo qué tan bien pueda mantenerlo, sino que lo concebirá como posible con él. Puede ser fácilmente la diferencia entre un programa que se convierte en un tiempo heredado hasta que alguien se da cuenta de cómo deshacerse de él, y uno que crece para seguir ofreciendo un retorno de la inversión.

0

Si se encuentra escribiendo if declaraciones para la misma condición una y otra vez, entonces será más fácil mantener esa parte de la jerarquía de tipos.

La razón es que si la lógica de esta condición cambia, deberá buscar cada declaración if que la usa y modificarla.

Si esa lógica está encapsulada en una jerarquía de clases, solo debería necesitar cambiarla una vez.

Cuestiones relacionadas