Как использовать timeit, когда каждый тест требует случайной настройки
У меня есть функция f(x)
который принимает в качестве входных данных список x
из 100 случайных чисел от 0 до 1. Различные списки приведут к разному времени выполнения f
,
Я хочу узнать как долго f
занимает в среднем по большому количеству разных случайных списков. Какой лучший способ сделать это? Должен ли я использовать timeit
и если да, то есть ли способ сделать это без учета времени, которое требуется для создания каждого случайного списка в каждом испытании?
Вот как бы я сделал это без timeit
(Псевдокод):
for i = 1 to 10000:
x = random list
start = current time
f(x)
end = current time
results.append(end - start)
return mean(results)
3 ответа
Вы можете сделать декоратор таймера:
Вот пример кода:
from time import time
class Timer(object):
def __init__(self, func):
"""
Decorator that times a function
@param func: Function being decorated
@type func: callable
"""
self.func = func
def __call__(self, *args, **kwargs):
start = time()
self.func(*args, **kwargs)
end = time()
return end - start
@Timer
def cheese():
for var in xrange(9999999):
continue
for var in xrange(100):
print cheese()
Рабочий пример с меньшим количеством циклов.
import timeit, random
def summer(myList):
result = 0
for num in myList:
result += num
return result
for i in range(10):
x = [random.randint(0, 100) for i in range(100000)]
print timeit.timeit("summer(x)", setup="from __main__ import x, summer", number = 100)
Вы можете импортировать переменную используя from __main__ import x
Я думаю, что это делает трюк. Это выполнит setup
один раз за повтор, а затем выполнить stmt
number=1
время. Однако я не думаю, что это намного лучше, чем простой цикл, который вы опубликовали.
import timeit
stmt = '[x*x*x for x in xrange(n)]' # just an example
setup = 'import random; n = random.randint(10, 100)'
r = 10000
times = timeit.repeat(stmt, setup, repeat=r, number=1)
print min(times), max(times), sum(times)/r
Существует также "режим ячейки", который вы можете использовать с timeit в оболочке IPython, но он возвращает только ускоренное время, и нет простого способа изменить это (?).
import random
%%timeit -r 10000 -n 1 n = random.randint(10,100)
var = [x*x*x for x in xrange(n)]