Performance of Try-Catch in PHP

Performance of try-catch in php

One thing to consider is that the cost of a try block where no exception is thrown is a different question from the cost of actually throwing and catching an exception.

If exceptions are only thrown in failure cases, you almost certainly don't care about performance, since you won't fail very many times per execution of your program. If you're failing in a tight loop (a.k.a: banging your head against a brick wall), your application likely has worse problems than being slow. So don't worry about the cost of throwing an exception unless you're somehow forced to use them for regular control flow.

Someone posted an answer talking about profiling code which throws an exception. I've never tested it myself, but I confidently predict that this will show a much bigger performance hit than just going in and out of a try block without throwing anything.

Another thing to consider is that where you nest calls a lot of levels deep, it can even be faster to have a single try...catch right at the top than it is to check return values and propagate errors on every call.

In the opposite of that situation, where you find that you're wrapping every call in its own try...catch block, your code will be slower. And uglier.

Do php 5 try catches affect performance when no exception is caught?

I ran a very small and unscientific test and found there to be roughly no difference between having a catch that never gets called or having it outside a try catch statement. I ran each of these two scripts 5 times each through my profiler and averaged the total times.

Results


  • With Try/Catch statement: 1.34 seconds
  • Without Try/Catch statement: 1.3 seconds

The Code


Try/Catch


<?php
foreach(range(1,200000) as $i) {
try {
if ($i % 5 == 0 && $i % 3 == 0) echo "fizzbuzz";
elseif ($i % 5 == 0) echo "fizz";
elseif ($i % 3 == 0) echo "buzz";
else echo $i;
} catch (Exception $e) {
echo sin($i) * cos($i * pi());
}
}

?>

No Try/Catch


<?php
foreach(range(1,200000) as $i) {
if ($i % 5 == 0 && $i % 3 == 0) echo "fizzbuzz";
elseif ($i % 5 == 0) echo "fizz";
elseif ($i % 3 == 0) echo "buzz";
else echo $i;
}

?>

PHP - Does try/catch have a higher overhead than if/then?

The whole point of try/catch is that it is non-local. You can exit multiple loops at a stroke, break out of nested function calls, escape from anywhere you get into. if can't do that, and is not meant to. I do not know about the overhead, but I strongly and informedly suspect that it has much more than if. Ultimately, use the tool right for the job: they are not interchangeable.

Okay, they are, but they shouldn't be interchanged :)

UPDATE: Many other people say that try/catch are for error handling. They are not. They are for exception handling. In many languages, for example, trying to get a next element from the iterator on its last element will raise an exception; this is a perfectly valid use of exceptions. You can use them whenever something unexpected happens, which has to be handled outside the current scope (assuming you are not providing a callback to handle it).

When to use Try Catch blocks

It seems to me that this topic is very strange and confused. Could someone lights me up?

Definitely. I'm not a PHP user, but I might have a little insight after having worked with try/catch in ActionScript, Java, and JavaScript. Bear in mind though, that different languages and platforms encourage different uses for try/catch. That said...

The only times I'd recommend using try/catch is if you're using a native language function that

  1. Can throw an error/exception
  2. Does not give you any tools to detect whether you're about to do something stupid that would cause that error/exception. eg: In ActionScript, closing a loader that is not open will result in an error but the loader doesn't have an isOpen property to check so you're forced to wrap it in try/catch to silence an otherwise totally meaningless error.
  3. The error/exception really is meaningless.

Let's take the examples you list and see how they square with that list.

I read someone saying that we should use try-catch blocks only to prevent fatal errors.

In the case of AS's loader.close() function, this is good advice. That's a fatal error, and all from an otherwise trivial misstep. On the other hand, virtually ALL errors in AS will bring your application to a halt. Would you then wrap them all in try/catch? Absolutely not! A "fatal error" is fatal for a reason. It means something terribly wrong has happened and for the application to continue on in a potentially "undefined" state is foolhardy. It's better to know an error happened and then fix it rather than just let it go.

I read someone else saying that we should use it only on unexpected errors

That's even worse. Those are presicely the errors you DON'T want to silence, because silencing them means that you're never going to find them. Maybe you're not swallowing them, though... maybe you're logging them. But why would you try/catch/log/continue as though nothing happened, allowing the program to run in a potentially dangerous and unexpected condition? Just let the error kick you in the teeth and then fix it. There's little more frustrating than trying to debug something that's wrong in a program that someone else wrote because they wrapped everything in a try/catch block and then neglected to log.

Others simply say that try-catch blocks should be used everywhere because they can be also extended (extending the Exception class).

There's potential merit to this if you're the one doing the throwing, and you're trying to alert yourself to an exceptional situation in your program... but why try/catch your own thrown error? Let it kick you in the teeth, then fix it so that you don't need to throw the error anymore.

Finally someone says that PHP try-catch block are totally useless because they are very bad implemented. (On this i find a nice SO question about performance).

Maybe so. I can't answer this one though.

So... this might be a bit of a religious question, and I'm certain people will disagree with me, but from my particular vantage point those are the lessons I've learned over the years about try/catch.

Exception handling performance

The answer is no, not in any significant way. I suppose over the course of thousands of calls, you might see a few microseconds (or less) difference between some code with a try/catch and some code without, but as try/catch is a language construct, you're not incurring significant overhead.

It's just the same as using a for loop, or an if/else.

The true test is to benchmark your code and see for yourself. ;)

Edit: I should clarify that the actual throwing and catching of an Exception may have some overhead involved, since an Exception object must be generated, etc. This is slightly different than just measuring the try/catch execution itself.

Performance: Using try (statement) and catch (output error) instead of checking if email already exist

After making uid column an [unique] index, you made all your queries faster. Both queries, either SELECT or INSERT will have to check the index, and it will take them both the same time to perform.

Adding an index to the column used for search for is the real answer to your question. As to whether to use a select query or to catch an exception during insert is a matter of taste.

However, your second example is rather wrong. You shouldn't handle every PDOException the same way but only a specific exception related to this very case, as it's shown in my PDO tutorial.

The best way would be to keep the unique index but add a keyword IGNORE to the query and then check the number of affected rows

$insertuser = $X['dbh']->prepare("INSERT IGNORE INTO user (uid) VALUES (:uid)");
$insertuser->execute(['uid'=> $mail]));
if (!$insertuser->numRows()) {
header("Location: ...");
exit();
}

adding IGNORE would suppress the unique index error, and you will be able to check whether such a value already exists by simply checking the number of affected rows

How to efficiently use try...catch blocks in PHP

Important note

The following discussion assumes that we are talking about code structured as in the example above: no matter which alternative is chosen, an exception will cause the method to logically stop doing whatever it was in the middle of.


As long as you intend to do the same thing no matter which statement in the try block throws an exception, then it's certainly better to use a single try/catch. For example:

function createCar()
{
try {
install_engine();
install_brakes();
} catch (Exception $e) {
die("I could not create a car");
}
}

Multiple try/catch blocks are useful if you can and intend to handle the failure in a manner specific to what exactly caused it.

function makeCocktail()
{
try {
pour_ingredients();
stir();
} catch (Exception $e) {
die("I could not make you a cocktail");
}

try {
put_decorative_umbrella();
} catch (Exception $e) {
echo "We 're out of umbrellas, but the drink itself is fine"
}
}


Related Topics



Leave a reply



Submit