通过timeit参数的时间函数/方法:简单&简短的解决方法

时间:2015-06-06 12:27:40

标签: python performance python-3.x time lambda

我猜我们在尝试使用自定义函数/方法的timeit并将参数传递给它时,所有人都看到timeit失败了ValueError: stmt is neither a string nor callable

E.g。

1> import timeit         
2>                       
3> def testing(a):       
4>     for i in range(0, 1000):
5>         a + 1     
6>                       
7> print (timeit.timeit(testing(5), number=1000))

如果没有进一步的设置/导入(在我看来这会使声明混淆),它将失败ValueError: stmt is neither a string nor callable,因为它无法找到。

所以,剩下的问题是:什么是小的,简约的(甚至是#34; pythonic")处理问题的方法?

我们如何通过pythons timeit的所有好处轻松计算代码片段来衡量执行时间?

2 个答案:

答案 0 :(得分:2)

将代码段放在一个字符串中,并将一个import语句添加到setup(也是一个字符串)中:

__main__

该脚本始终称为testing(5)

从Python 2.6开始,语句和设置参数都采用没有参数的函数,因此您可以将timeit()调用包装在lambda或simple函数中。考虑到这需要额外开销来运行;来自timeit.Timer() class documentation

  

stmt setup 参数也可以使用不带参数的可调用对象。这将在计时器函数中嵌入对它们的调用,然后由{{1}}执行。 请注意,由于额外的函数调用,在这种情况下,时序开销会略大一些。

在比较不同的方法时要考虑到这一点,不要混用这两种风格。

答案 1 :(得分:0)

我发现的一个答案(在我看来是一个很好的答案)是将你想要调用的函数包装到另一个无参数函数中。当然这会产生一点开销并且会增加可读性......这就是为什么lambdas对于这个小黑客来说是一个很好的解决方法:

1> import timeit               
2>                             
3> def testing(a):             
4>     for i in range(0, 1000):
5>         a + 1           
6>                             
7> print (timeit.timeit(lambda: testing(5), number=1000))

Output> 0.0097241420746

我们疯狂的唯一变化是第7行:不是直接调用测试,而是用lambda函数包装它。现在 timeit 不必担心未知参数,因为它会传递一个干净的,包装好的匿名函数。

另一个好处是 python 2.7.X和python 3.X 中都有效,没有任何更改:)