Cost of exception handlers in Python

PythonPerformanceExceptionMicro Optimization

Python Problem Overview


In another question, the accepted answer suggested replacing a (very cheap) if statement in Python code with a try/except block to improve performance.

Coding style issues aside, and assuming that the exception is never triggered, how much difference does it make (performance-wise) to have an exception handler, versus not having one, versus having a compare-to-zero if-statement?

Python Solutions


Solution 1 - Python

Why don't you measure it using the timeit module? That way you can see whether it's relevant to your application.

OK, so I've just tried the following:

import timeit

statements=["""\
try:
    b = 10/a
except ZeroDivisionError:
    pass""",
"""\
if a:
    b = 10/a""",
"b = 10/a"]

for a in (1,0):
    for s in statements:
        t = timeit.Timer(stmt=s, setup='a={}'.format(a))
        print("a = {}\n{}".format(a,s))
        print("%.2f usec/pass\n" % (1000000 * t.timeit(number=100000)/100000))

Result:

a = 1
try:
    b = 10/a
except ZeroDivisionError:
    pass
0.25 usec/pass

a = 1
if a:
    b = 10/a
0.29 usec/pass

a = 1
b = 10/a
0.22 usec/pass

a = 0
try:
    b = 10/a
except ZeroDivisionError:
    pass
0.57 usec/pass

a = 0
if a:
    b = 10/a
0.04 usec/pass

a = 0
b = 10/a
ZeroDivisionError: int division or modulo by zero

So, as expected, not having any exception handler is slightly faster (but blows up in your face when the exception happens), and try/except is faster than an explicit if as long as the condition is not met.

But it's all within the same order of magnitude and unlikely to matter either way. Only if the condition is actually met, then the if version is significantly faster.

Solution 2 - Python

This question is actually answered in the Design and History FAQ:

> A try/except block is extremely efficient if no exceptions are raised. > Actually catching an exception is expensive.

Solution 3 - Python

This question is misleading. If you assume the exception is never triggered, neither one is optimal code.

If you assume the exception is triggered as part of an error condition, you are already outside the realm of wanting optimal code (and you probably aren't handling it at a fine-grained level like that anyway).

If you are using the exception as part of the standard control flow - which is the Pythonic "ask forgiveness, not permission" way - then the exception is going to be triggered, and the cost depends on the kind of exception, the kind of if, and what percentage of time you estimate the exception happens.

Solution 4 - Python

In Python 3.11,

“Zero-cost” exceptions are implemented. The cost of try statements is almost eliminated when no exception is raised. (Contributed by Mark Shannon in bpo-40222.)

https://docs.python.org/3.11/whatsnew/3.11.html#optimizations

Solution 5 - Python

Q: Is try/catch costly in python?

Should i be concerned when I use try catch? In what way?

This is just a summary of the answers already given.

A: When there is an exception if is much faster. Otherwise no.

@SuperNova writes that exceptions are at zero cost so it is faster than having an if-statement when no exception. However, handling exceptions is costly so:

Use try for things that can fail. If possible, avoid try for things you know will fail
Example:
  1. Good case, use try:
try:
    x = getdata() # an external function 
except:
    print('failed. Retrying')
  1. Bad case, here if-version is preferred:
y = f(x) # f never fails but often returns 0
try:
    z = 1 / y # this fails often
except:
    print('failed.')

# if-version
y = f(x)
if y != 0:
    z = 1 / y
else:
    print('failed.')

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThiloView Question on Stackoverflow
Solution 1 - PythonTim PietzckerView Answer on Stackoverflow
Solution 2 - PythonMichaelView Answer on Stackoverflow
Solution 3 - Pythonuser79758View Answer on Stackoverflow
Solution 4 - PythonSuperNovaView Answer on Stackoverflow
Solution 5 - PythonHunaphuView Answer on Stackoverflow