2009-11-16 14 views
5

Preguntas relacionadas: Benefits of using short-circuit evaluation, Why would a language NOT use Short-circuit evaluation?, Can someone explain this line of code please? (Logic & Assignment operators)¿Por qué usar el código de cortocircuito?

Hay preguntas sobre los beneficios de una lengua utilizando el código de cortocircuito, pero me pregunto ¿cuáles son los beneficios para un programador? ¿Es solo que puede hacer que el código sea un poco más conciso? ¿O hay razones de rendimiento?

No estoy preguntando por situaciones en las dos entidades necesitan ser evaluados de todas formas, por ejemplo:

if($user->auth() AND $model->valid()){ 
    $model->save(); 
} 

Para mí, el razonamiento no está claro - ya que ambos necesitan para ser verdad, puede saltar más validación del modelo costoso si el usuario no puede guardar los datos.

Esto también tiene un (a mí) propósito obvio:

if(is_string($userid) AND strlen($userid) > 10){ 
    //do something 
}; 

Debido a que no sería prudente llamar strlen() con un valor distinto de cadena.

Lo que me pregunto es sobre el uso del código de cortocircuito cuando no afecta a ninguna otra declaración. Por ejemplo, desde la página de índice predeterminado Zend Aplicación:

defined('APPLICATION_PATH') 
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 

Esto podría haber sido:

if(!defined('APPLICATION_PATH')){ 
    define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 
} 

o incluso como una sola instrucción:

if(!defined('APPLICATION_PATH')) 
    define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); 

Así que ¿por qué utilizar a corto código de circuito? ¿Solo por el factor 'frialdad' de usar operadores lógicos en lugar de estructuras de control? Para consolidar declaraciones if anidadas? Porque es más rápido?

+0

Una nota sobre la velocidad: si tiene un compilador medio decente, generará el mismo código de máquina para declaraciones y cortocircuitos. Si no lo hace, está produciendo un código lo suficientemente malo como para que algunos ciclos extra de alguna microoptimización a nivel de fuente se pierdan en el ruido. Muy simplemente, no es importante. –

+0

@David ¿Eso también sería cierto para los lenguajes de scripting? –

+0

@TimLytle en idiomas interpretados, puede tener diferentes comportamientos debido a los diferentes análisis e interpretaciones que se deben realizar. Los compiladores se benefician de eso antes de que el código tenga la oportunidad de ejecutarse. –

Respuesta

4

Para los programadores, el beneficio de una sintaxis menos detallado sobre otra sintaxis más detallado puede ser:

  • que escribir menos, por lo tanto, una mayor eficiencia de codificación
  • menos a leer, por lo tanto, una mejor capacidad de mantenimiento.

Ahora solo estoy hablando cuando la sintaxis menos verbosa no es complicada o inteligente de ninguna manera, solo la misma manera reconocida de hacerlo, pero en menos caracteres.

A menudo, cuando ve construcciones específicas en un idioma, desea que el lenguaje que utiliza pueda tener, pero no necesariamente se haya dado cuenta antes. Algunos ejemplos fuera de mi cabeza:

  • clases internas anónimas en Java en lugar de pasar un puntero a una función (forma más líneas de código).
  • en Ruby, el operador || =, para evaluar una expresión y asignarla si se evalúa como falsa o es nula. Claro, puedes lograr lo mismo con 3 líneas de código, pero ¿por qué?
  • y muchos más ...
0

¿Qué pasa si tiene una función costosa para llamar (rendimiento) que devuelve un booleano en el lado derecho que solo desea llamar si otra condición es verdadera (o falsa)? En este caso, el cortocircuito le ahorra muchos ciclos de CPU. Hace que el código sea más conciso debido a menos declaraciones if anidadas. Entonces, por todos los motivos que mencionó al final de su pregunta.

+0

Sí, ese es uno de los ejemplos que cito como una razón obvia. Vea el ejemplo $ model-> valid(). –

+0

Exactamente. Todas las razones que cita son muy buenas razones para usar la evaluación de cortocircuito. – Poindexter

4

¡Úselo para confundir a las personas!

+0

O tal vez para evitar que el (riff) raff (fácilmente confundido) se meta con el código. – NVRAM

4

No sé PHP y nunca he visto un cortocircuito utilizarse fuera de un si o mientras condición en la familia de las lenguas C, pero en Perl es muy idiomática decir:

open my $filehandle, '<', 'filename' or die "Couldn't open file: $!"; 

Uno La ventaja de tenerlo todo en una declaración es la declaración de la variable. De lo contrario, tendría que decir:

my $filehandle; 
unless (open $filehandle, '<', 'filename') { 
    die "Couldn't open file: $!"; 
} 

Es difícil reclamar que el segundo sea más limpio en ese caso. Y sería aún más prolijo en un lenguaje que no tiene unless

+2

Menos cosas para escribir hace felices a los programadores. – nos

2

Creo que su ejemplo es para el factor de frescor. No hay razón para escribir código así.

EDITAR: No tengo ningún problema con hacerlo por razones idiomáticas. Si todos los demás que usan un idioma utilizan la evaluación de cortocircuito para crear entidades similares a las declaraciones que todo el mundo entienda, entonces usted también debería hacerlo.Sin embargo, mi experiencia es que el código de ese tipo rara vez se escribe en los lenguajes de la familia C; La forma correcta es simplemente usar la instrucción "if" como normal, que separa el condicional (que presumiblemente no tiene efectos secundarios) de la llamada de función que los controles condicionales (que presumiblemente tiene muchos efectos secundarios).

1

relacionado con lo que dijo Dan, pensaría que todo depende de las convenciones de cada lenguaje de programación. No veo ninguna diferencia, así que haga lo que sea idiomático en cada lenguaje de programación. Una cosa que podría hacer la diferencia que viene a la mente es si tienes que hacer una serie de comprobaciones, en ese caso el estilo de cortocircuito sería mucho más claro que el estilo alternativo si.

0

La verdad es en realidad el rendimiento. El cortocircuito se usa en los compiladores para eliminar el ahorro de código muerto en el tamaño del archivo y la velocidad de ejecución. En el cortocircuito en tiempo de ejecución, no ejecuta la cláusula restante en la expresión lógica si su resultado no afecta la respuesta, lo que acelera la evaluación de la fórmula. Estoy luchando por recordar un ejemplo. por ejemplo

A y B y c

hay dos términos de esta fórmula evaluados de izquierda a derecha.

si a AND b se evalúa como FALSO, entonces la siguiente expresión AND c puede ser FALSA Y VERDADERA o FALSA Y FALSA. Ambos evalúan a FALSO sin importar el valor de c. Por lo tanto, el compilador no incluye AND c en el formato compilado, por lo tanto, se produce un cortocircuito en el código.

Para responder a la pregunta, hay casos especiales en los que el compilador no puede determinar si la expresión lógica tiene una salida constante y, por lo tanto, no provocará un cortocircuito en el código.

2

operadores cortocircuito puede ser útil en dos circunstancias importantes que aún no se han mencionado:

Caso 1. Supongamos que tiene un puntero que puede o no ser NULL y quería comprobar que no era NULL, y que lo que señalaba no era 0. Sin embargo, debe no desreferenciar el puntero si es NULO.Sin operadores de cortocircuito, que tendría que hacer esto:

if (a != NULL) { 
    if (*a != 0) { 
    ⋮ 
    } 
} 

Sin embargo, los operadores de cortocircuito permiten escribir esto de forma más compacta:

if (a != NULL && *a != 0) { 
    ⋮ 
} 

con la certeza de que *a se no evaluarse si a es NULL.

Caso 2. Si desea establecer una variable a un valor que no sea falsa regresar de una de una serie de funciones, sólo tiene que hacer:

my $file = $user_filename || 
      find_file_in_user_path() || 
      find_file_in_system_path() || 
      $default_filename; 

Esto establece el valor de $file a $user_filename si está presente, o el resultado de find_file_in_user_path(), si es verdad, o ... etc. Esto se ve quizás más a menudo en Perl que en C, pero lo he visto en C.

Existen otros usos, incluidos los ejemplos bastante artificiales que usted cita arriba. Pero son una herramienta útil, y una que me he perdido al programar en lenguajes menos complejos.

+0

Esa es la 'consolidación de declaraciones anidadas' que no recuerdo haber visto en el pasado o creo que el código de ejemplo. –

0

creo que de esta manera, si usted tiene una declaración como

if(A AND B) 

Es probable que si devuelve FALSO Un solo jamás desea evaluar B en casos especiales raras. Por esta razón, NO usar la evaluación corta del ciruit es confuso.

La evaluación de corto circuito también hace que su código sea más legible al evitar otra sangría entre corchetes y los corchetes tienen una tendencia a sumarse.