2008-08-29 9 views
5

Tengo una declaración if con dos condiciones (separadas por un operador OR), una de las condiciones cubre + 70% de situaciones y toma mucho menos tiempo para procesar/ejecutar que la segunda condición, por lo que en intereses de la velocidad solo quiero que se procese la segunda condición si la primera condición se evalúa como falsa.si optimización de condición de instrucción

si ordeno las condiciones para que la primera condición (la más rápida) aparezca primero en el estado if - en las ocasiones en que se cumple esta condición y se evalúa verdadero, ¿se procesa incluso la segunda condición?

if ((condition1) | (condition2)){ 
    // do this 
} 

o qué necesitaría para anidar dos si declaraciones a sólo verifican la segunda condición si la primera se evalúa como falsa?

if (condition1){ 
    // do this 
}else if (condition2){ 
    // do this 
} 

Estoy trabajando en php, sin embargo, supongo que esto puede ser independiente del idioma.

Respuesta

9

Para C, C++, C#, Java y otros lenguajes .NET, las expresiones booleanas se optimizan para que, tan pronto como se sepa, no se evalúe nada más.

Un viejo truco para hacer código ofuscado era utilizar esto para crear las sentencias if, tales como:

a || b(); 

si "a" es cierto, nunca serían evaluados "() b", por lo que podemos reescribir en:

if(!a) 
    b(); 

y de manera similar:

a && b(); 

se convertiría en

if(a) 
    b(); 

Tenga en cuenta que esto solo es válido para || y & & operador. Los dos operadores | y & es bit a bit y, yy, respectivamente, y por lo tanto no están "optimizados".

EDIT: Como lo mencionaron otros, tratando de optimizar el código utilizando la lógica de cortocircuito es muy raro que pase el tiempo.

Primero, para mayor claridad, porque es más fácil de leer y entender. Además, si intenta ser demasiado inteligente, un simple reordenamiento de los términos podría llevar a comportamientos muy diferentes sin ninguna razón aparente.

En segundo lugar, vaya para la optimización, pero solo después del tiempo y el perfil. Demasiados desarrolladores hacen una optimización prematura sin crear perfiles.La mayoría de las veces es completamente inútil.

0

Dado que esto está etiquetado como idioma agnóstico, lo llamaré. Para Perl, al menos, la primera opción es suficiente, no estoy familiarizado con PHP. Se evalúa de izquierda a derecha y se retira tan pronto como se cumple la condición.

3

Casi todos los idiomas hacen una evaluación de cortocircuito. Lo que significa que la segunda condición solo se evalúa si es absolutamente necesario. Para que esto funcione, la mayoría de los idiomas usan el doble tubo, ||, no el único, |.

Ver http://en.wikipedia.org/wiki/Short-circuit_evaluation

0

En la mayoría de los idiomas con la optimización de la antigua decente funcionará bien.

2

he visto una gran cantidad de este tipo de preguntas últimamente - optimización a la enésima potencia.

creo que tiene sentido en ciertas circunstancias:

  1. de condiciones de cálculo 2 no es una operación constante de tiempo
  2. Usted está pidiendo estrictamente para fines educativos - quieres saber cómo funciona el idioma, no para salvar 3us.

En otros casos, la preocupación de la forma "más rápida" para iterar o comprobar un condicional es tonta. En lugar de escribir pruebas que requieren millones de ensayos para ver cualquier diferencia registrable (pero insignificante), concéntrese en la claridad.

Cuando otra persona (¿podría ser usted?) Recoge este código en un mes o un año, lo que será más importante es la claridad.

En este caso, el primer ejemplo es más corto, más clara y no necesita que repita a sí mismo.

2

De acuerdo con this article PHP realiza la evaluación de cortocircuitos, lo que significa que si se cumple la primera condición, el segundo ni siquiera se evalúa. Es bastante fácil de probar también (del artículo):

<?php 
/* ch06ex07 – shows no output because of short circuit evaluation */ 

if (true || $intVal = 5) // short circuits after true 
{ 

echo $intVal; // will be empty because the assignment never took place 
} 

?> 
3

En C, C++ y Java, la declaración:

 
if (condition1 | condition2) { 
    ... 
} 

will evaluate both conditions every time and only be true if the entire expression is true.

The statement:


if (condition1 || condition2) { 
    ... 
} 

evaluará condition2 sólo si condition1 es falso. La diferencia es significativa si condition2 es una función u otra expresión con un efecto secundario. Sin embargo, no hay diferencia entre el caso || y el caso if/else.

0

El | es un operador de bits en PHP. No significa $a OR $b, exactamente. Querrá usar el doble tubo. Y sí, como se mencionó, PHP realiza una evaluación de cortocircuito. De manera similar, si la primera condición de una cláusula && se evalúa como falsa, PHP tampoco evalúa el resto de la cláusula.

1

Si bien el uso de cortocircuitos a los fines de la optimización suele ser exagerado, existen sin duda otras razones de peso para utilizarlo. Un ejemplo de ello (en C++) es la siguiente:

if(pObj != NULL && *pObj == "username") { 
    // Do something... 
} 

Aquí, los cortocircuitos está siendo invocado para asegurar que pObj se han asignado antes de la eliminación de referencias ella. Esto es mucho más conciso que anidar las declaraciones if.

0

VB.net tiene dos expresión maravillosa llamada "OrElse" y "AndAlso"

OrElse hará corto circuito en sí la primera vez que llega a una verdadera evaluación y ejecutar el código que desee.

If FirstName = "Luke" OrElse FirstName = "Darth" Then 
    Console.Writeline "Greetings Exalted One!" 
End If 

AndAlso será corto circuito en sí la primera vez que una evaluación falsa y no evaluar el código dentro del bloque.

If FirstName = "Luke" AndAlso LastName = "Skywalker" Then 
    Console.Writeline "You are the one and only." 
End If 

Encuentro estos dos útiles.

+1

Eso es exactamente lo que || y && do en la mayoría de los otros idiomas, respectivamente. –

2

El cortocircuito no es para la optimización. Su objetivo principal es evitar el código de llamada que no funcionará, pero dará lugar a una prueba legible. Ejemplo:

if (i < array.size() && array[i]==foo) ... 

Tenga en cuenta que array [i] puede muy bien tener una violación de acceso si está fuera de rango y bloquee el programa. ¡Por lo tanto, este programa ciertamente depende de un cortocircuito en la evaluación!

Creo que esta es la razón para escribir expresiones de esta manera mucho más a menudo que las preocupaciones de optimización.

Cuestiones relacionadas