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?
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.
As a rule of thumb, exception handling is extremely cheap when you don't throw an exception. It costs nothing on some implementations. All the cost is incurred when you throw an exception: that is, “normal code” is faster than code using error-return codes and tests. You incur cost only when you have an error.
In general, when a Python script encounters a situation that it cannot cope with, it raises an exception. An exception is a Python object that represents an error. When a Python script raises an exception, it must either handle the exception immediately otherwise it terminates and quits.
Making use of Python exception handling has a side effect, as well. Like, programs that make use try-except blocks to handle exceptions will run slightly slower, and the size of your code will increase.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With