Python timeit 使用困难

2 投票
2 回答
1970 浏览
提问于 2025-04-18 16:51

我在使用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中,这就像tictoc那么简单。我想在Python中对应的命令是用'time.clock()'在函数调用前后,但我听说这可能不准确,容易误导。

2 个回答

0

未来的一个小提示:

我最近提交了一个补丁,针对的是问题2527,这个补丁几天前已经被合并到默认分支了。所以,当3.5版本正式发布时,你可以这样做:

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

我知道这没有iPython的%timeit那么酷,但比现在你必须做的from __main__ import ...要好很多。更多信息可以查看文档

2

你不需要在每次的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语句里的代码被执行。这意味着如果你导入了你的函数,就不会意外地运行你的计时测试。

这段代码只导入了func3x。我只对func3感兴趣(不关心func1func2),而且我定义了一个值来进行测试(我叫它x,但它和你的my_input是一样的)。在这种情况下,你不需要导入numpy。

不过,我还是强烈建议你考虑一下roippi的评论,使用IPython。%timeit这个魔法命令非常非常有用。

撰写回答