[Tutor] Try except really better than if?
Steven D'Aprano
steve at pearwood.info
Mon Jan 10 01:22:33 CET 2011
Karim wrote:
>
> Hello all,
>
> I am using more and more try except statement. But I discussed with a
> very experienced C++ programmer.
> And he told me that at least in C++ using too many try -catch statements
> are making the code slower. And it should
> does the same for python (C implementation).
He is right with the first part, wrong with the second. Python's
exceptions are not the same as C++ or Java exceptions.
Setting up a try...except block is *very* fast, unlike C++ and Java,
where it is slow. In Python, this code:
try:
1+1 # cannot fail
except ValueError:
pass
is just as fast as:
pass # null op, does nothing
1+1 # cannot fail
So there is no speed penalty for setting up a try...except block. If you
have something that will nearly always succeed, you don't need to be
concerned about using an exception handler.
However, *catching* the exception is more expensive. (Roughly ten times
as expensive.) So you should avoid code that mostly fails.
Remember, also, that the alternative to try...except also has a cost
which might not be cheap. You can do this:
try:
something that might fail
except Failure:
do alternative
or you can do this:
if something should succeed:
do something
else:
do alternative
But this if...else test is not free. Depending on how expensive the test
is, and how often you take each branch, it might be more expensive to
"look before you leap". Also, remember that many tests are disguised
exceptions, such as the builtin "hasattr" function:
# pseudo-code
def hasattr(obj, name):
try:
getattr(obj, name)
except AttributeError:
return False
return True
So there is no speed advantage to calling:
if hasattr(obj, 'spam'):
print(obj.spam)
else:
print("no spam in object")
over this:
try:
print(obj.spam)
except AttributeError:
print("no spam in object")
The first may even be slower because it has to look up the attribute
twice -- this is what I call a pessimation, something done in the name
of speed which actually makes your code *slower*.
Catching exceptions are best in three circumstances:
- You only care about the speed of a successful operation. Failures can
be slow. If your program prints an error message and then exits, who
cares if it takes 3 milliseconds longer than necessary?
- Testing whether something will succeed is impossible, or expensive, or
too hard to get right.
- Failures are rare. As a *very* rough rule of thumb, I say that if you
expect a failure less than one time in ten, it is better to use
try...except.
But mostly, don't worry about speed. If you are worried about
*execution* speed, you shouldn't be using Python in the first place.
Python is optimized for developer productivity, not execution speed.
Write your code, and *if* it is too slow, then worry about finding the
bottlenecks and optimizing them.
Some very important quotes about optimization in general:
“More computing sins are committed in the name of efficiency (without
necessarily achieving it) than for any other single reason - including
blind stupidity.” - W.A. Wulf
“We should forget about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil. Yet we should not pass
up our opportunities in that critical 3%. A good programmer will not be
lulled into complacency by such reasoning, he will be wise to look
carefully at the critical code; but only after that code has been
identified.” - Donald Knuth
“Bottlenecks occur in surprising places, so don't try to second guess
and put in a speed hack until you have proven that's where the
bottleneck is.” - Rob Pike
“The First Rule of Program Optimization: Don't do it. The Second Rule of
Program Optimization (for experts only!): Don't do it yet.” - Michael A.
Jackson
--
Steven
More information about the Tutor
mailing list