funciona - Rendimiento de try-catch en php
try catch php mysqli (8)
¡Esa es una muy buena pregunta!
Lo he probado muchas veces y nunca vi ningún problema de rendimiento ;-) Fue cierto hace 10 años en C ++, pero creo que hoy lo han mejorado mucho ya que es muy útil y más limpio.
Pero todavía tengo miedo de rodear mi primer punto de entrada con él:
try {Controller::run();}catch(...)
No probé con muchas funciones, llamada y gran inclusión .... ¿Alguien ya lo ha probado por completo?
¿Qué tipo de implicaciones de rendimiento hay que considerar al usar declaraciones try-catch en php 5?
He leído información anterior y aparentemente contradictoria sobre este tema en la web antes. Mucho del framework con el que actualmente tengo que trabajar fue creado en php 4 y carece de muchas de las sutilezas de php 5. Por lo tanto, no tengo mucha experiencia en el uso de try-catchs con php.
En general, son caros y no valen la pena en PHP.
Como es un lenguaje de expresiones comprobadas, DEBE capturar cualquier cosa que arroje una excepción.
Cuando se trata de código heredado que no arroja, y el nuevo código que lo hace, solo genera confusión.
¡Buena suerte!
En general, use una excepción para protegerse contra fallas inesperadas y use la comprobación de errores en su código contra fallas que son parte del estado normal del programa. Para ilustrar:
Registro no encontrado en la base de datos - estado válido, debe verificar los resultados de la consulta y enviar mensajes al usuario de manera apropiada.
Error de SQL al intentar recuperar el registro: error inesperado, el registro puede estar o no, pero tiene un error de programa: este es un buen lugar para una excepción: registrar el error en el registro de errores, enviar al administrador el seguimiento de la pila y mostrar un cortés mensaje de error para el usuario informándole que algo salió mal y que está trabajando en ello.
Las excepciones son costosas, pero a menos que maneje todo el flujo de su programa utilizándolas, cualquier diferencia en el rendimiento no debe ser perceptible por los humanos.
Estaba aburrido y perfilé lo siguiente (dejé el código de tiempo):
function no_except($a, $b) {
$a += $b;
return $a;
}
function except($a, $b) {
try {
$a += $b;
} catch (Exception $e) {}
return $a;
}
usando dos bucles diferentes:
echo ''no except with no surrounding try'';
for ($i = 0; $i < NUM_TESTS; ++$i) {
no_except(5, 7);
}
echo ''no except with surrounding try'';
for ($i = 0; $i < NUM_TESTS; ++$i) {
try {
no_except(5, 7);
} catch (Exception $e) {}
}
echo ''except with no surrounding try'';
for ($i = 0; $i < NUM_TESTS; ++$i) {
except(5, 7);
}
echo ''except with surrounding try'';
for ($i = 0; $i < NUM_TESTS; ++$i) {
try {
except(5, 7);
} catch (Exception $e) {}
}
Con 1000000 ejecuciones en mi caja de WinXP, ejecute apache y PHP 5.2.6:
no except with no surrounding try = 3.3296
no except with surrounding try = 3.4246
except with no surrounding try = 3.2548
except with surrounding try = 3.2913
Estos resultados fueron consistentes y se mantuvieron en una proporción similar sin importar el orden en que se realizaron las pruebas.
Conclusión: Agregar código para manejar excepciones raras no es más lento que el código ignora las excepciones.
Los bloques Try-catch no son un problema de rendimiento; el cuello de botella de rendimiento real proviene de la creación de objetos de excepción.
Código de prueba:
function shuffle_assoc($array) {
$keys = array_keys($array);
shuffle($keys);
return array_merge(array_flip($keys), $array);
}
$c_e = new Exception(''n'');
function no_try($a, $b) {
$a = new stdclass;
return $a;
}
function no_except($a, $b) {
try {
$a = new Exception(''k'');
} catch (Exception $e) {
return $a + $b;
}
return $a;
}
function except($a, $b) {
try {
throw new Exception(''k'');
} catch (Exception $e) {
return $a + $b;
}
return $a;
}
function constant_except($a, $b) {
global $c_e;
try {
throw $c_e;
} catch (Exception $e) {
return $a + $b;
}
return $a;
}
$tests = array(
''no try with no surrounding try''=>function() {
no_try(5, 7);
},
''no try with surrounding try''=>function() {
try {
no_try(5, 7);
} catch (Exception $e) {}
},
''no except with no surrounding try''=>function() {
no_except(5, 7);
},
''no except with surrounding try''=>function() {
try {
no_except(5, 7);
} catch (Exception $e) {}
},
''except with no surrounding try''=>function() {
except(5, 7);
},
''except with surrounding try''=>function() {
try {
except(5, 7);
} catch (Exception $e) {}
},
''constant except with no surrounding try''=>function() {
constant_except(5, 7);
},
''constant except with surrounding try''=>function() {
try {
constant_except(5, 7);
} catch (Exception $e) {}
},
);
$tests = shuffle_assoc($tests);
foreach($tests as $k=>$f) {
echo $k;
$start = microtime(true);
for ($i = 0; $i < 1000000; ++$i) {
$f();
}
echo '' = ''.number_format((microtime(true) - $start), 4)."<br>/n";
}
Resultados:
no try with no surrounding try = 0.5130
no try with surrounding try = 0.5665
no except with no surrounding try = 3.6469
no except with surrounding try = 3.6979
except with no surrounding try = 3.8729
except with surrounding try = 3.8978
constant except with no surrounding try = 0.5741
constant except with surrounding try = 0.6234
No he encontrado nada en el rendimiento de Try / Catch en Google, pero una prueba simple con un error de lanzamiento de bucle en lugar de una instrucción IF produce 329ms vs 6ms en un bucle de 5000.
Perdón por publicar un mensaje muy antiguo, pero leí los comentarios y estoy un tanto en desacuerdo, la diferencia podría ser mínima con un simple fragmento de código, o podría ser negligible utilizar Try / Catch para partes específicas del código que no son siempre predecible, pero también creo (no probado) que un simple:
if(isset($var) && is_array($var)){
foreach($var as $k=>$v){
$var[$k] = $v+1;
}
}
es más rápido que
try{
foreach($var as $k=>$v){
$var[$k] = $v+1;
}
}catch(Exception($e)){
}
También creo (no probado) que a:
<?php
//beginning code
try{
//some more code
foreach($var as $k=>$v){
$var[$k] = $v+1;
}
//more code
}catch(Exception($e)){
}
//output everything
?>
es más caro que tener IF adicionales en el código
Una cosa a considerar es que el costo de un bloque de prueba donde no se lanza una excepción es una pregunta diferente del costo de lanzar y atrapar una excepción.
Si solo se lanzan excepciones en casos de falla, es casi seguro que no le importa el rendimiento, ya que no fallará muchas veces por ejecución de su programa. Si está fallando en un círculo cerrado (también conocido como golpearse la cabeza contra una pared de ladrillos), es probable que su aplicación tenga peores problemas que la lentitud. Así que no se preocupe por el costo de lanzar una excepción a menos que de alguna manera se vea obligado a usarlos para un flujo de control regular.
Alguien ha publicado una respuesta sobre el código de creación de perfiles que arroja una excepción. Nunca lo probé yo mismo, pero predigo confiadamente que esto mostrará un golpe de rendimiento mucho mayor que solo entrar y salir de un bloque de prueba sin tirar nada.
Otra cosa a tener en cuenta es que cuando anida llamadas a muchos niveles de profundidad, incluso puede ser más rápido tener una sola oportunidad ... atrapar en la parte superior de lo que es para verificar los valores de retorno y propagar los errores en cada llamada.
En el lado opuesto a esa situación, donde observa que está envolviendo cada llamada en su propio intento ... atrapar bloque, su código será más lento. Y más feo