2011-09-23 177 views
60

我这个使用timeit挣扎,并想知道如果任何人有,我想测试的速度任何提示如何在将变量传递给函数时使用python 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 

如果我对自己的运行功能,它工作正常。它的时候,我包装它的时候它模块,我得到的错误(我试过使用双引号,没有..sameoutput)。

任何建议都会很棒!

谢谢!

回答

95

让它可以调用的:

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

应工作

+0

工作正常!非常感谢。我需要弄清楚什么是lambda ..看起来像是有所作为。谢谢Pablo – Lostsoul

+5

如果只有这个在文档 – endolith

+13

哦,但lambda增加了一些开销,所以不适合测试小的东西。 'timeit 5 * 5'为33 ns,而'timeit(lambda:5 * 5)()'为233 ns。 – endolith

16

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

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

感谢您的回答oxtopus!它不起作用,当我把它包装在引号中,所以它的字符串我得到这个错误:NameError:全球名称'superMegaIntenseFunction'未定义。你认为我还能尝试什么? – Lostsoul

+0

更正了包含设置参数的答案。 (http://docs.python。org/library/timeit.html#timeit.Timer) –

21

Timer(superMegaIntenseFunction(10))的意思是 “叫superMegaIntenseFunction(10),然后将结果传递给Timer”。这显然不是你想要的。 Timer需要可调用(就像它听起来:可以调用的东西,比如函数)或字符串(以便它可以将字符串的内容解释为Python代码)。 Timer通过重复调用可调用事物并查看需要多少时间来工作。

Timer(superMegaIntenseFunction)会通过类型检查,因为superMegaIntenseFunction是可调用的。但Timer不知道要传递给superMegaIntenseFunction的值是多少。

解决这个问题的简单方法当然是在代码中使用字符串。我们需要传递一个'setup'参数给代码,因为在新的上下文中字符串被“解释为代码” - 它不能访问相同的代码,所以你需要运行另一个代码来创建定义可用 - 请参阅@ oxtopus的答案。

使用lambda(如@Pablo的答案),我们可以将参数10绑定到调用superMegaIntenseFunction。我们正在做的所有事情是创建另一个函数,它不带任何参数,并调用superMegaIntenseFunction10。就好像您使用def来创建另一个函数一样,除了新函数没有得到名称(因为它不需要)。

1

针对未来访客的备注。如果你需要使它在pdb调试工作,superMegaIntenseFunction是不是在全球范围内,你可以把它的工作,加入到globals

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

Note that the timing overhead is a little larger in this case because of the extra function calls. [source]