2011-08-10 12 views

Respuesta

8

Debido a que || siendo (en C, Java, C#, php) "cortocircuitado" (si el primer operando es verdadero, el segundo no se evalúa porque la expresión ya se ha evaluado como verdadera, sin importar cuál sea el segundo.

Así que este es C-estilo clásico "brevedad" en acción su uso como un menor número de líneas de código como sea posible, a pesar de que su haciendo exactamente lo mismo como algo más longhand

para que se lea:.. si está definido (...), no hagas el bit de definición() ... si no está definido(), intenta evaluar el bit de definición() y en el proceso definirá la constante.

+0

Entonces la sintaxis 'defined ('CONSTANT') o define ('CONSTANT', somedefinition);' no es válida porque 'o'operator no está" cortocircuitado "? –

+0

@David Casillas: Lo es. Mire en mi respuesta para la explicación de la diferencia entre '||' y 'o' – Mchl

+0

@Mchl, estaba pensando que' o' no estaba 'en cortocircuito', pero es simplemente '||' con diferente precedencia. –

3
defined('CONSTANT') || define('CONSTANT', somedefinition); 

De hecho, es un truco. Ya ves, el || el operador solo ejecuta la segunda parte de la expresión cuando la primera parte es falsa :) Es una forma rápida y corta de escribir el mismo código de funcionamiento.

+3

La palabra clave aquí es * Evaluación de cortocircuito *. – deceze

+0

Algunos lenguajes tienden a usarlo de manera preeminente (perl), por lo que quizás los que lo hacen en php lo hagan principalmente por hábito. ¿Alguna idea de si hay alguna diferencia de rendimiento? – Joubarc

4

Otros han respondido primero parte de su pregunta, entonces tomaré esto último:

En cuanto a or frente a || está preocupado, no hay diferencia en este caso específico. Sin embargo, or tiene operator precedence más bajo que = (operador de asignación), mientras que || tiene más alto. Esto es significativo, si desea usar el cortocircuito para hacer la asignación.

considerar:

$a = 2 or $b = 2; 
var_dump($a); // int(2) 


$a = 3 || $b = 3; 
var_dump($a); // bool(true) 

En segundo ejemplo, || obtuve evaluados antes =. Usando paréntesis se vería como esto

$a = (3 || $b = 3); 

mientras el primero

($a = 2) or ($b = 2); 
1

Así que mi suposición es el cortocircuito es más rápido, ya que la sentencia if está tomando el valor booleano de definir y darle la vuelta utilizando un operador no, pero sólo para ser exhaustiva, aquí está mi prueba de referencia:


PHP 5.6:

0.23026204109192 - Prueba 1a: Cortocircuito: definición dinámica en el primer ciclo.
0.22264909744263 - Prueba1b: instrucción If: definición dinámica en el primer ciclo.
0.22433304786682 - Prueba 2a: Cortocircuito: Static define antes de ejecutar la prueba.
0.22339177131653 - Test2b: instrucción If: Definición estática antes de ejecutar la prueba.
0.27459692955017 - Prueba3a: Cortocircuito: Nunca se define la variable.
0.28696393966675 - Test3b: Si enunciado: Nunca definir variable.

Conclusión
Demasiado cerca para contar, aunque podemos ver una mejora notable de la velocidad de cortocircuito si la variable no está definida.


PHP 7:

0,031289100646973 - Test1a: Cortocircuito: Dinámico definir el primer bucle.
0.041652917861938 - Test1b: Declaración If: definición dinámica en el primer ciclo.
0.023349046707153 - Prueba 2a: Cortocircuito: Static define antes de ejecutar la prueba.
0.052791118621826 - Test2b: instrucción If: Definición estática antes de ejecutar la prueba.
0.064755916595459 - Prueba3a: Cortocircuito: Nunca se define la variable.
0.056003093719482 - Test3b: Declaración: Nunca se define la variable.

Conclusión PHP 7 optimiza claramente para el corto circuito en el caso de las constantes/variables definidas, aunque vemos el contrario si la constante no está definido. Esto implica que la comprobación de las constantes que realmente existen se ha mejorado drásticamente, lo que facilita ver el procesamiento adicional que requiere el operador no agregado en la sentencia if.

Conclusión En general

La diferencia es insignificante (a menos que se está metiendo los millones de cargas de la misma línea de código) a fin de utilizar lo que tiene más sentido para usted y su equipo.

Además, ¡hombre, PHP7 fuma PHP 6.5 en términos de rendimiento de estas pruebas!


Código:

$c1a=0; 
$title1a = 'Test1a: Short circuit: Dynamic define on first loop.'; 
$c1b=0; 
$title1b = 'Test1b: If Statement: Dynamic define on first loop.'; 

$c2a=0; 
$title2a = 'Test2a: Short circuit: Static define before test is run.'; 
$c2b=0; 
$title2b = 'Test2b: If Statement: Static define before test is run.'; 

$c3a=0; 
$title3a = 'Test3a: Short circuit: Never define variable.'; 
$c3b=0; 
$title3b = 'Test3b: If Statement: Never define variable.'; 

$start1a = microtime(true); 
while ($c1a < 1000000) { 
    ++$c1a; 
    defined('TEST_CONST_1A') || define('TEST_CONST_1A', 'test'); 
} 
$stop1a = microtime(true); 

$start1b = microtime(true); 
while ($c1b < 1000000) { 
    ++$c1b; 
    if (!defined('TEST_CONST_1B')) { 
    define('TEST_CONST_1B', 'test'); 
    } 
} 
$stop1b = microtime(true); 

define('TEST_CONST_2A', 'test'); 
$start2a = microtime(true); 
while ($c2a < 1000000) { 
    ++$c2a; 
    defined('TEST_CONST_2A') || define('TEST_CONST_2A', 'test'); 
} 
$stop2a = microtime(true); 

define('TEST_CONST_2B', 'test'); 
$start2b = microtime(true); 
while ($c2b < 1000000) { 
    ++$c2b; 
    if (!defined('TEST_CONST_2B')) { 
    define('TEST_CONST_2B', 'test'); 
    } 
} 
$stop2b = microtime(true); 

$start3a = microtime(true); 
while ($c3a < 1000000) { 
    ++$c3a; 
    defined('TEST_CONST_3A') || $c3a; 
} 
$stop3a = microtime(true); 

$start3b = microtime(true); 
while ($c3b < 1000000) { 
    ++$c3b; 
    if (!defined('TEST_CONST_3B')) { 
    $c3b; 
    } 
} 
$stop3b = microtime(true); 

print ($stop1a - $start1a) . ' - ' . $title1a . "\n"; 
print ($stop1b - $start1b) . ' - ' . $title1b . "\n"; 
print ($stop2a - $start2a) . ' - ' . $title2a . "\n"; 
print ($stop2b - $start2b) . ' - ' . $title2b . "\n"; 
print ($stop3a - $start3a) . ' - ' . $title3a . "\n"; 
print ($stop3b - $start3b) . ' - ' . $title3b . "\n"; 
Cuestiones relacionadas