将变量传递给函数时如何使用python timeit?


76

我正在使用timeit进行此操作,并且想知道是否有人有任何提示

基本上,我有一个要测试其速度的函数(将值传递给它),并创建了这个函数:

if __name__=='__main__':
    from timeit import Timer
    t = Timer(superMegaIntenseFunction(10))
    print t.timeit(number=1)

但是当我运行它时,会出现奇怪的错误,例如来自timeit模块。

ValueError: stmt is neither a string nor callable

如果我自己运行该功能,则效果很好。当我将其包装在time模块中时,出现错误(我尝试使用双引号而不使用..sameoutput)。

任何建议都很棒!

谢谢!

Answers:


126

使其可调用:

if __name__=='__main__':
    from timeit import Timer
    t = Timer(lambda: superMegaIntenseFunction(10))
    print(t.timeit(number=1))

应该管用


可行!非常感谢。我需要弄清楚lambda的作用是什么。感谢Pablo
Lostsoul 2011年

6
如果仅在某处的文档中提供了这些信息,请访问
endolith 2013年

17
哦,但是lambda会增加一些开销,因此不是测试小物件的理想选择。timeit 5*5是33 ns,timeit (lambda: 5*5)()而是233 ns。
endlith 2013年

太棒了。我只是timeit用lambda调用时遇到了问题(脚本冻结;我测量执行时间的方法是retrbinary使用进行FTP下载的方法ftplib)。一旦我使用了该Timer物体,它突然就像一种魅力一样起作用。不知道发生了什么...:D
rbaleksandar '18

23

Timer(superMegaIntenseFunction(10))表示“调用superMegaIntenseFunction(10),然后将结果传递给Timer”。显然这不是您想要的。Timer期望一个可调用的(听起来很像:可以被调用的东西,例如一个函数)或一个字符串(以便它可以将字符串的内容解释为Python代码)。Timer通过反复调用可调用事物并查看花费了多少时间来工作。

Timer(superMegaIntenseFunction)将通过类型检查,因为它superMegaIntenseFunction是可调用的。但是,Timer不知道要传递什么值superMegaIntenseFunction

当然,解决此问题的简单方法是在代码中使用字符串。我们需要将“ setup”参数传递给代码,因为字符串是在新的上下文中“解释为代码”的,因为它无法访问该字符串globals,因此您需要运行另一段代码来进行定义可用-参见@oxtopus的答案。

使用lambda(如@Pablo的回答),我们可以将参数绑定到10对的调用superMegaIntenseFunction。所有这一切,我们正在做的是创造另一个功能,即不带任何参数,并呼吁superMegaIntenseFunction10。就像您曾经使用def过那样创建另一个函数一样,只是新函数没有名称(因为它不需要一个)。


18

您应该传递一个字符串。即

t = Timer('superMegaIntenseFunction(10)','from __main__ import superMegaIntenseFunction')

感谢您的答案oxtopus!当我将其用引号引起来时,它不起作用,因此它是一个字符串,但出现以下错误:NameError:未定义全局名称'superMegaIntenseFunction'。您认为我还能尝试什么?
Lostsoul

更正了答案以包括设置arg。(docs.python.org/library/timeit.html#timeit.Timer
奥斯汀马歇尔

1

给未来访客的说明。如果您需要使其在pdb调试器中运行,并且superMegaIntenseFunction不在全局范围内,则可以通过添加至来使其运行globals

globals()['superMegaIntenseFunction'] = superMegaIntenseFunction
timeit.timeit(lambda: superMegaIntenseFunction(x))

请注意,在这种情况下,由于额外的函数调用,时序开销会稍大一些。[资源]


0

一种实现方法是使用Partial,以便函数“ superMegaIntenseFunction”在计时器中或直接在timeit.timeit内部用作可调用函数(即不使用())。当使用计时器时,使用partial将参数传递给函数。

from functools import partial
from timeit import timeit

print(timeit(partial(superMegaIntenseFunction, 10), number=1))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.