Python timeit 使用困难
我在使用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
还有很多其他内容。
我该如何测量这个函数的时间呢?从更深层次来看,为什么在Python中会这么麻烦?我已经定义了一个变量和一个函数;我只想用那个变量来测量函数调用的时间。要是能不写超长的代码行,或者不写多行代码,或者不需要导入任何东西就好了。在Matlab中,这就像tic
和toc
那么简单。我想在Python中对应的命令是用'time.clock()'在函数调用前后,但我听说这可能不准确,容易误导。
2 个回答
未来的一个小提示:
我最近提交了一个补丁,针对的是问题2527,这个补丁几天前已经被合并到默认分支了。所以,当3.5版本正式发布时,你可以这样做:
timeit.timeit('level_99_function(x)', globals=globals())
我知道这没有iPython的%timeit
那么酷,但比现在你必须做的from __main__ import ...
要好很多。更多信息可以查看文档。
你不需要在每次的setup
里都导入numpy,其实你可以用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的评论,使用IPython。%timeit
这个魔法命令非常非常有用。