Reputation: 3405
Let's say I'm trying to measure the execution time of a sorting function, here is my code:
import timeit
def time_algo(sort_fun, input_seq, num=100):
'''
Time how long it takes to sort sequence 'input_seq' using
function 'sort_fun'. Take min of 'num' times.
'''
foo = list(input_seq)
wrapped = wrapper(sort_fun, foo)
return min(timeit.repeat(wrapped, repeat=num, number=1))
def wrapper(func, *args):
def wrapped():
return func(*args)
return wrapped
print time_algo(list.sort, [10,9,8,7,6,5,4,3,2,1], num = 100)
The problem is that after the first execution of sort_fun
, the input list is already sorted, and it's running on a sorted list for the rest of num - 1
times.
How can I initialize the arguments for the input function (in this case execute foo = list(input_seq)
) before every repetition of function timing? Or what would be the proper way to do this using the timeit
module (I need accurate results so i don't want to use other timing methods like time.clock()
etc.)?
Upvotes: 2
Views: 808
Reputation: 526
I think this modified time_algo()
does what you want:
def time_algo(sort_fun, input_seq, num=100):
'''
Time how long it takes to sort sequence 'input_seq' using
function 'sort_fun'. Take min of 'num' times.
'''
foo = list(input_seq)
wrapped = wrapper(sort_fun, foo)
def reset_foo():
foo[:] = list(input_seq)
return min(timeit.timeit(wrapped, setup=reset_foo, number=1) for _ in range(num))
This re-copies input_seq to list foo before each timeit(). There less-fancy / more-manual ways of doing it that could be more general: you could write a plain loop which copies the input, makes a new wrapper, and calls timeit.
... but as commented above, you really want multiple iterations, per timeit, and for that you really want to be timing a function which does not modify its inputs.
Upvotes: 3