2014-08-11 4 views
2

Я борюсь с функцией timeit в Python, и, на более глубоком уровне, я очень расстроен причудами этой функции. Я надеюсь, что я смогу помочь в решении этих проблем.Борьба с Python timeit

У меня есть сценарий (назовите его my_script.py) с множеством различных определений функций, а затем подсчитывается множество других вещей под ними. Я хочу, в частности, только одну из этих функций - назовем ее level_99_function(x). У меня большой массив, хранящийся в my_input. Моя первая попытка:

timeit.timeit('f1(x)', setup = 'my_input') 

Python возвращает ошибку: NameError: global name 'angle' is not defined.

Теперь моя вторая попытка сделать следующее:

print timeit.timeit('level_99_function(x)', setup = 'import numpy as np; import my_script.py; x= np.linspace(0,100)') 

Это не создает каких-либо ошибок, но проблема состоит в два раза. Во-первых, и что самое главное, он все еще не время level_99_function (или, может быть, он просто не печатает на выходе таймера по какой-либо причине?) Во-вторых, оператор import, кажется, запускает весь скрипт при импорте, который принимает навсегда из-за всего, что у меня есть в этом сценарии, кроме моего level_99_function.

Как получить информацию о текущей функции здесь? И на более философском уровне, почему эта такая борьба на Питоне? У меня уже есть переменная и определенная функция; все, что я хочу сделать, - это время вызова этой функции с этой переменной. Было бы неплохо не писать сверхдолговую строку кода или писать несколько строк кода, или им нужно импортировать вещи или любой другой материал. Это так же просто, как tic и toc в Matlab. Я думаю, что соответствующие команды Python будут использовать «time.clock()» до и после вызова функции, но я прочитал, что это может быть неточным и вводящим в заблуждение.

+0

_ "Операция импорта, похоже, запускает весь скрипт при импорте" _. Возможно, вам понадобится ['if __name__ ==" __main__ ":'] (http://stackoverflow.com/questions/419163/what-does-if-name-main-do) защита вокруг всего не-функционального кода в ваш модуль. – Kevin

+0

'timeit' не эквивалентен' tic ... toc'. Если вам нужна функциональность 'tic ... toc', сделайте что-то вроде:' start = time.clock(); My_function(); print time.clock() - start' –

+3

Re: ваше разочарование: сделайте себе одолжение и вместо этого используйте iPython с магией «% timeit», чтобы сравнить ваши вещи. Он превосходит ванильный 'timeit' во многих отношениях. В остальном вам нужно будет предоставить больше кода. Мы можем * догадаться *, но это не то, для чего вы пришли сюда. – roippi

ответ

2

Вам не нужно импортировать numpy каждый раз в пределах setup, вместо этого вы можете импортировать функцию и переменные из текущего сценария с from __main__ import ..., как показано в примере ниже.

import timeit 
import numpy as np 

def func1(x): 
    pass 

def func2(x): 
    pass 

def func3(x): 
    return np.array(x > 1000) 


if __name__ == '__main__': 
    x = np.arange(10000) 

    time = timeit.timeit('func3(x)', setup='from __main__ import func3, x', number=1000) 
    print(time) 

if __name__ == '__main__' блок предотвратит коду в if заявлении от того, побежал если импортировать код из другого сценария, то есть вы случайно не запустить тесты синхронизации, если вы импортировать функции.

Этот код только импортирует func3 и x. Меня интересует только func3 (не func1 и func2), и я определил значение для проверки с помощью (я называю это x, но это эквивалентно вашему my_input). В этом случае вам не нужно импортировать numpy.

Я бы полностью и полностью посоветовал принять во внимание roippi's comment и использовать IPython. Магический метод %timeit очень, очень полезен.

+0

Спасибо за советы всем. Определенно просто собираюсь использовать команду% timeit iPython. – hobscrk777

0

В качестве FYI для будущего:

Я недавно представил патч против issue2527, который был committed a few days ago филиала по умолчанию. Поэтому всякий раз, когда 3.5 публично выпущен, вы можете сделать это:

timeit.timeit('level_99_function(x)', globals=globals()) 

Не совсем, как удивительным, как IPython-х %timeit, я знаю, но гораздо лучше, чем from __main__ import ... нонсенс, что вам нужно сделать прямо сейчас. More info in the docs.

Смежные вопросы