timeit versus timing decorator timeit versus timing decorator python python

timeit versus timing decorator


Use wrapping from functools to improve Matt Alcock's answer.

from functools import wrapsfrom time import timedef timing(f):    @wraps(f)    def wrap(*args, **kw):        ts = time()        result = f(*args, **kw)        te = time()        print 'func:%r args:[%r, %r] took: %2.4f sec' % \          (f.__name__, args, kw, te-ts)        return result    return wrap

In an example:

@timingdef f(a):    for _ in range(a):        i = 0    return -1

Invoking method f wrapped with @timing:

func:'f' args:[(100000000,), {}] took: 14.2240 secf(100000000)

The advantage of this is that it preserves attributes of the original function; that is, metadata like the function name and docstring is correctly preserved on the returned function.


I would use a timing decorator, because you can use annotations to sprinkle the timing around your code rather than making you code messy with timing logic.

import timedef timeit(f):    def timed(*args, **kw):        ts = time.time()        result = f(*args, **kw)        te = time.time()        print 'func:%r args:[%r, %r] took: %2.4f sec' % \          (f.__name__, args, kw, te-ts)        return result    return timed

Using the decorator is easy either use annotations.

@timeitdef compute_magic(n):     #function definition     #....

Or re-alias the function you want to time.

compute_magic = timeit(compute_magic)


Use timeit. Running the test more than once gives me much better results.

func_list=[locals()[key] for key in locals().keys()            if callable(locals()[key]) and key.startswith('time')]alist=range(1000000)times=[]for f in func_list:    n = 10    times.append( min(  t for t,_,_ in (f(alist,31) for i in range(n)))) for (time,func_name) in zip(times, func_list):    print '%s took %0.3fms.' % (func_name, time*1000.)

->

<function wrapper at 0x01FCB5F0> took 39.000ms.<function wrapper at 0x01FCB670> took 41.000ms.