Rendimiento de try-catch en php

¿Qué tipo de implicaciones de rendimiento hay que tener en cuenta al usar instrucciones try-catch en php 5?

He leído información antigua y aparentemente contradictoria sobre este tema en la web antes. Gran parte del marco 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.

Respuestas:9 Respuestas 9
Tiempo:hace 14 años
Última modificación:hace 2 años, 5 meses

Solución

Una cosa a considerar es que el costo de un bloque de prueba donde no se lanza ninguna excepción es una cuestión 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 bucle apretado (también conocido como golpearse la cabeza contra una pared de ladrillos), es probable que su aplicación tenga peores problemas que ser lenta. 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 el flujo de control regular.

Alguien publicó una respuesta hablando sobre el código de creación de perfiles que arroja una excepción. Nunca lo he probado yo mismo, pero predigo con confianza que esto mostrará un éxito de rendimiento mucho mayor que simplemente entrar y salir de un bloque de prueba sin lanzar nada.

Otra cosa a tener en cuenta es que donde anidas llama a muchos niveles de profundidad, incluso puede ser más rápido tener un solo intento … captura justo en la parte superior de lo que es para verificar los valores de retorno y propagar errores en cada llamada.

En lo opuesto a esa situación, donde descubres que estás envolviendo cada llamada en su propio intento… catch block, su código será más lento. Y más feo.

Otras respuestas

Los bloques try-catch no son un problema de rendimiento: el verdadero cuello de botella de rendimiento 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

Deja un comentario