Cole
Cole

Reputation: 2509

Python speed testing -- why does an except failure cost so much time

I assumed a try / except workflow would be faster than an if / then workflow for the simple action 'try to remove x from list_l'. In the below example, the except failures (x not in list_l) cost more times than permission requests (if x is in list_l) even though there chance of an exception is 16.6% of the time. Why?

Here are the tests I coded and their results:

import random, time, timeit

class Timer(object):
    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, *args):
        self.end = time.time()
        self.secs = self.end - self.start
        self.msecs = self.secs * 1000  # millisecs

def a_function():
    a_list = list(xrange(10))
    choice_list = list(xrange(12))
    choice = random.choice(choice_list)
    try:
        a_list.remove(choice)

    except ValueError:
        pass

def b_function():
    a_list = list(xrange(10))
    choice_list = list(xrange(12))
    choice = random.choice(choice_list)
    if choice in a_list:
        a_list.remove(choice)

with Timer() as a:
    print('test_a', timeit.timeit("a_function()", number=10000, setup="from __main__ import a_function"))

with Timer() as b:
    print('test_b', timeit.timeit("b_function()", number=10000, setup="from __main__ import b_function"))

The results:

1st attempt: ('test_a', 0.029724836349487305)('test_b', 0.027068138122558594)

2nd attempt: ('test_a', 0.02960801124572754)('test_b', 0.026785850524902344)

3rd attempt: ('test_a', 0.029654979705810547)('test_b', 0.02665996551513672)

Also, if I increase the choice_list range to 20, the difference widens because exceptions occur more frequently. If python is strongly ask-forgiveness-not-permission, why does failure seem to cost some much in terms of time?

Upvotes: 0

Views: 121

Answers (2)

Thomas Schultz
Thomas Schultz

Reputation: 2467

This is a total stab in the dark but it could be due to exception handling being class based and if/then being purely logic based. So the interpreter can optimize simple conditional handing far more than it can class flows.

http://docs.python.org/release/2.5/whatsnew/pep-352.html

Upvotes: 0

Linuxios
Linuxios

Reputation: 35788

Exceptions are very expensive in any language, and this is a misuse of them.

Exceptions are meant for exceptional circumstances that your code cannot account for and that are not expected to come up during normal operations. Different languages have different rules for what is exceptional, but something that happens 16% of the time is not exceptional, just unusual.

Exceptions are expensive because they involve a stack unwind and a jump, pausing of normal processing, and a search for a handler. If/then is a standard, normal conditional that is efficient and clear.

Upvotes: 6

Related Questions