Как использовать 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 один раз за повтор, а затем выполнить stmtnumber=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)]
Другие вопросы по тегам