'Measure runtime of function with arguments using timeit.timeit

I would like to create a function. The code doesn't work, but you can get the idea what I want to get:

def time_test(func, test_data: int) -> float:
    # should return a runtime of given function
    return timeit(stmt=func(test_data), number=10000)

Obviously, I do have to pass as stmt something callable or a string with executable code. That's why it doesn't work, but I don't know how to do this in a correct way.

Example how I want to use time_test() function:

from timeit import timeit
# To be tested
def f1(argument_ops):
    result = 0
    for i in range(argument_ops):
        result += 4
    return result

def f2(argument_ops):
    result = 0
    for i in range(argument_ops):
        for j in range(argument_ops):
            result += 4
    return result

# test function to be implemented
def time_test(func, test_data: int) -> float:
    runtime = 0
    # implement this, it should return a runtime of a given function. Function needs
    # argument test_data.
    return runtime

# example of usage
print(time_test(f1, 96))
print(time_test(f2, 24))


Solution 1:[1]

Actually, I think you can use the globals argument, which takes a namespace in which to execute the statement, to do this relatively easily. Something to the effect of:

def time_test(func, test_data: int) -> float:
    gs = dict(func=func, test_data=test_data)
    runtime = timeit("func(test_data)", globals=gs)
    # implement this, it should return a runtime of a given function. Function needs argument test_data.
    return runtime

Note, by default this times how long it takes to the statement 1000000 times.

Solution 2:[2]

I would suggest doing it this way which involves passing the function definition to the time_test() function as well as the function name and arguments:

from timeit import timeit

# To be tested
f1_def = """
def f1(argument_ops):
    result = 0
    for i in range(argument_ops):
        result += 4
    return result
"""

f2_def = """
def f2(argument_ops):
    result = 0
    for i in range(argument_ops):
        for j in range(argument_ops):
            result += 4
    return result
"""

# test function
def time_test(func, test_data: int, setup: str) -> float:
    stmt = f'{func}({test_data!r})'
    runtime = timeit(stmt, setup)
    return runtime

# example of usage
print(time_test('f1', 96, setup=f1_def))  # -> 4.069019813000001
print(time_test('f2', 24, setup=f2_def))  # -> 34.072881441999996

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 martineau