I have a decorator that I wrote that will time a given function. It seems to work well with any function, except for recursive functions.
Decorator:
def tictoc(repeats=3, loops=1): def t(func): from functools import partial, wraps import timeit @wraps(func) def timer(*args, **kargs): elapsed = timeit.repeat(partial(func, *args, **kargs), repeat = repeats, number=loops) mine = min(elapsed) print "%s finished in %.5fs (%d loops, %d times) with %.5fs per loop" % (func.__name__, mine, loops, repeats, mine/loops) return timer return t the recursive function is the basic Fibonacci algorithm.
@tictoc() def fib(i): return ( 0 if i == 0 else 1 if i == 1 else fib(i-1) + fib(i-2) ) fib(15) The program fails with the following error
fib finished in 0.00000s (1 loops, 3 times) with 0.00000s per loop fib finished in 0.00000s (1 loops, 3 times) with 0.00000s per loop fib finished in 0.00000s (1 loops, 3 times) with 0.00000s per loop Traceback (most recent call last): File "decor.py", line 61, in <module> [fib(x) for x in range(1,50)] File "/home/grout/Dropbox/Python/tictoc.py", line 7, in timer elapsed = timeit.repeat(partial(func, *args, **kargs), repeat = repeats, number=loops) File "/usr/lib/python2.7/timeit.py", line 233, in repeat return Timer(stmt, setup, timer).repeat(repeat, number) File "/usr/lib/python2.7/timeit.py", line 221, in repeat t = self.timeit(number) File "/usr/lib/python2.7/timeit.py", line 194, in timeit timing = self.inner(it, self.timer) File "/usr/lib/python2.7/timeit.py", line 100, in inner _func() File "decor.py", line 59, in fib fib(i-1) + fib(i-2) ) TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType' What I don't understand is how the decorator executes a few times and then fails. Any help would be appreciated.