Python - 类内使用Timeit
我在一个类的实例中计时一个函数时遇到了一些麻烦。我不太确定自己是不是在正确的方式上(之前从没用过timeIt),我尝试了几种不同的方式来导入第二个参数,但都没有成功。下面是我正在做的一个简单例子:
import timeit
class TimedClass():
def __init__(self):
self.x = 13
self.y = 15
t = timeit.Timer("self.square(self.x, self.y)")
try:
t.timeit()
except:
t.print_exc()
def square(self, _x, _y):
print _x**_y
myTimedClass = TimedClass()
运行这个代码时,它会抱怨关于self的问题。
Traceback (most recent call last):
File "timeItTest.py", line 9, in __init__
t.timeit()
File "C:\Python26\lib\timeit.py", line 193, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
self.square(self.x, self.y)
NameError: global name 'self' is not defined
这和TimeIt创建了一个小的虚拟环境来运行这个函数有关,但我需要给第二个参数传什么才能让它正常工作呢?
5 个回答
8
要解决你最开始遇到的错误,你可以在一个类里面使用timeit,并且可以像这样传入参数:
t = timeit.Timer(lambda: self.square(self.x, self.y)).timeit()
9
你为什么想要在类里面自己计时呢?如果把计时功能放到类外面,你可以直接传一个引用进去。也就是说:
import timeit
class TimedClass():
def __init__(self):
self.x = 13
self.y = 15
def square(self, _x, _y):
print _x**_y
myTimedClass = TimedClass()
timeit.Timer(myTImedClass.square).timeit()
(当然,这个类本身可能有点多余,我猜你有更复杂的情况,简单的方法不够用)。
一般来说,直接传一个可以调用的东西,里面包含所有的设置和配置。如果你想传字符串来计时,它们应该自己包含所有必要的设置,也就是说:
timeit.Timer("[str(x) for x in range(100)]").timeit()
如果你真的非常需要在类里面进行计时,可以把调用包裹在一个本地方法里,也就是说:
def __init__(self, ..):
def timewrapper():
return self.multiply(self.x, self.y)
timeit.Timer(timewrapper)
10
如果你愿意考虑一些替代方案来代替 timeit
,我最近发现了一个叫做 stopwatch 的计时工具,这可能对你有帮助。它非常简单易用,直观明了:
import stopwatch
class TimedClass():
def __init__(self):
t = stopwatch.Timer()
# do stuff here
t.stop()
print t.elapsed