Grace Hopper 's famous quote :
It is easier to ask for forgiveness than to ask for permission.
Which is popular within the programming community, makes me wonder if this applies to Python code, I often feel inclined (for ease) to use exceptions. Consider the following case:
lista = []
# Pedir perdón
try:
elemento = lista[0]
except IndexError:
elemento = None
# Pedir permiso
elemento = None
if len(lista) > 1:
elemento = lista[0]
In summary what I want to know is, is there any performance difference in Python when using one or the other?
I ask this because I have heard from a friend that in Java, for example, it is expensive to use the block try {} catch {}
due to a series of processes carried out to fill the stack trace which makes you think carefully before using them. Does the same happen for Python?
Depending on what the goal of the program is, if your goal is performance ( in time ), a try-catch block becomes expensive, compared to an if , when it catches an exception.
But if robustness is what you're after , good exception handling is always preferable. In addition, good exception handling helps code interpretation from a logical point of view.
Here is an example of the cpu processing time used by each block, you can see that the if block uses less cpu time when the try catches the exception compared to the conditional block
I believe that @Santi92's answer is correct, the best way is to do a type of benchmark to know the result, but not with one iteration but with several thousand.
However, in the interest of sharing knowledge on this topic, I found the following using the
timeit
Python module:Result:
With which it can be concluded that "asking for forgiveness" is faster than "asking for permission" as long as the exception is not raised. Which affirms what some mentioned in the comments.
References:
I commented that the try is only slower in general terms when it catches the exception, this is an example:
. This part shown below is the interesting one (the try is faster than the if when it doesn't jump)
.this part that is shown below is a filler because the try jumps and also performs the operation, that's why it jumps ha, and in the if it only compares from there that it be faster
Taking your analogy at face value, we have two truths, until someone proves otherwise.
Just be sorry if you've made a mistake, however, you should ALWAYS ask for permission, out of courtesy ;).
Now, taking this into account, why mention which one is easier? Let's handle exceptions as you say, it is not more difficult or easier than validating the information, for example.
For me that would be the rule, as long as time allows you to ask for permission, and you should only ask for forgiveness in cases that are currently outside your preliminary analysis.
The best in "performance" is:
If you are never going to be wrong or almost never, ask for forgiveness, and don't waste time asking for permission.
If you are wrong many times, ask for permission, which will cost you less than asking for several forgiveness.
And keep in mind that 1 million permissions consumes much more than a pardon.
But that 1 million permits consumes much less than half a million pardons.
In your case, I would speculate, what is the tendency of your code. In performance matters , it is cheaper to apologize for making the assumption that the system is well analyzed, designed and coded.
This is very similar to the concept of branch prediction .
If you notice that the code throws more exceptions than following the programmed flow, then you must ask for permission each time you want to do the operation that throws the exception.
Now, if the operation doesn't tend to throw exceptions, then I apologize.