Cost of raising exceptions.
aleaxit at yahoo.com
Tue May 29 17:29:24 CEST 2001
"Allan Crooks" <amc1 at dcs.qmw.ac.uk> wrote in message
news:mailman.991144423.30414.python-list at python.org...
> Are raising exceptions a costly operation?
Up to a point.
> But since that has a high overhead, the hasNext() method is a way of
> detecting the end. My query is, if developing something similar for
> Python, is raising an exception a good way to halt or not?
Just consider that THIS is how Python's for statement ALWAYS
works internally: it exits when it gets an IndexError from
the sequence it's indexing...
Let's take a concrete example. For some peculiar reason
I want to compute summations of numbers of the form 17/d,
where d = i modulo X, for i from 0 to N-1 included, but
simply skipping the cases where the divisor d would be 0
(which will be one in every X numbers, of course). How
slow would it be to do it the simplest obvious way:
result = 0L
for i in range(N):
result += 17/(N%x)
versus a way that checks carefully instead:
result = 0L
for i in range(N):
divisor = N%x
result += 17/divisor
??? It's simpler to measure (with care:-) than to worry
start1 = time.clock(); r1=with_exceptions(N,x); stend1 = time.clock()
start2 = time.clock(); r2=without_them(N,x); stend2 = time.clock()
print "%d/%d: %d==%d, with ex:%.2f without:%.2f" % (
N, x, r1, r2, stend1-start1, stend2-start2)
1000000/17: 3000016==3000016, with ex:11.64 without:9.14
1000000/7: 5571423==5571423, with ex:16.14 without:8.62
1000000/3: 8333325==8333325, with ex:26.15 without:7.40
So: if we're having an exception about one time in 20, the
cost of the exceptions-in-loop approach is about 20%. If
one time in 7, exceptions are about twice as costly as
checks in this case. If one in 3, exceptions cost a
slow-down of over 1 in three.
But this is for reasonably light other-operations and rather
frequent 'exceptions'. In most cases, the real costs are
not so terrible -- particularly if the checking approach
should incur substantial overhead at each pass through
the loop while the exception approach only pays (albeit
a higher cost) on rare occasions... you might even end
up with exceptions being faster!-)
In the end, you're better off programming with the single
main goal of SIMPLICITY. If somebody may want to check
"is there more stuff?" WITHOUT consuming a next-item, then
giving them a .hasNext() method to call will be a good
thing, saving the contortions of trying to get-next, and
undo, within a try/except/else. That is generally a better
goal to keep in mind than marginal performance issues...
*KEEP IT SIMPLE* and be happy. Exceptions will be good
if they enable for-loop usage, too... client-code for
iteration doesn't get much simpler than that:-). But for
that you need specifically to raise IndexError within
__getitem__ when you have no more items (it gets better
in 2.2 with iterators, though... you won't any more
have to fake being random-access when you aren't:-).
More information about the Python-list