Home > database >  How do I use timeit module inside a decorator
How do I use timeit module inside a decorator

Time:01-06

I'm creating a decorator to primarily timeit any function it decorates. And I'm unable to get it right. Throws max recursion depth error. Could someone please help me understand why it is happening and how to achieve this timeit implementation. I don't want to use time module

import timeit
from functools import wraps


def tool(func):
    """Include debug statement and timeit setup"""
    @wraps(func)
    def wrapper(*args):
        print func.__doc__, args,
        res = func(*args)
        print res
        CODE = "func{args}".format(args=args)
        times = timeit.repeat(
            stmt=CODE,
            setup="from __main__ import {func} as func".format(func=func.__name__),
            repeat=3, number=10000)
        print times
    return wrapper

CodePudding user response:

the problem as I mention is in the setup, doing that import get you the already decorated function, that when executed once again do the import and get the decorated function and goes and execute the import and soo on until it blow up the stack... and we don't want that.

The timeit module can also take function as its stmt, so with just building a lambda function it solve the problem and we can use the undercoated function that way

The stmt and setup parameters can also take objects that are callable without arguments. This will embed calls to them in a timer function that will then be executed by timeit(). Note that the timing overhead is a little larger in this case because of the extra function calls.

import timeit
from functools import wraps
    
def tool(func):
    """Include debug statement and timeit setup"""
    @wraps(func)
    def wrapper(*args):
        print(func.__doc__, args)
        res = func(*args)
        print(res)
        times = timeit.repeat(
            stmt=lambda: func(*args),
            repeat=3, number=10000)
        print(times)
    return wrapper

and a quick test

>>> @tool
def fun():
    return 42
>>> fun()
None ()
42
[0.0013318000000026586, 0.0013294000000314554, 0.0013452000000597764]
>>> 
  •  Tags:  
  • Related