我正在使用Windows上的python进行编程,并希望准确地测量函数运行所需的时间。我编写了一个函数“time_it”,它接受另一个函数,运行它,并返回运行所花费的时间。
def time_it(f, *args):
start = time.clock()
f(*args)
return (time.clock() - start)*1000
我称之为1000次,并对结果取平均值。 (最后的1000常量是以毫秒为单位给出答案。)
这个功能似乎有效,但我有这种唠叨的感觉,我做错了,通过这样做,我使用的时间超过了它运行时实际使用的功能。
有更标准或可接受的方法吗?
当我更改我的测试函数以调用打印以使其花费更长时间时,我的time_it函数返回平均2.5 ms,而cProfile.run('f()')返回并平均为7.0 ms。我认为我的功能会高估时间,如果有什么,这里发生了什么?
另外需要注意的是,我所关心的功能相对时间是相对的,而不是绝对时间,因为这显然会因硬件和其他因素而异。
答案 0 :(得分:69)
使用Python标准库中的timeit
module。
基本用法:
from timeit import Timer
# first argument is the code to be run, the second "setup" argument is only run once,
# and it not included in the execution time.
t = Timer("""x.index(123)""", setup="""x = range(1000)""")
print t.timeit() # prints float, for example 5.8254
# ..or..
print t.timeit(1000) # repeat 1000 times instead of the default 1million
答案 1 :(得分:37)
我建议您查看内置的Python分析器(profile
或cProfile
,而不是编写自己的分析代码,具体取决于您的需求):http://docs.python.org/library/profile.html
答案 2 :(得分:30)
您可以像这样创建一个“timeme”装饰器
import time
def timeme(method):
def wrapper(*args, **kw):
startTime = int(round(time.time() * 1000))
result = method(*args, **kw)
endTime = int(round(time.time() * 1000))
print(endTime - startTime,'ms')
return result
return wrapper
@timeme
def func1(a,b,c = 'c',sleep = 1):
time.sleep(sleep)
print(a,b,c)
func1('a','b','c',0)
func1('a','b','c',0.5)
func1('a','b','c',0.6)
func1('a','b','c',1)
答案 3 :(得分:23)
此代码非常不准确
total= 0
for i in range(1000):
start= time.clock()
function()
end= time.clock()
total += end-start
time= total/1000
此代码不太准确
start= time.clock()
for i in range(1000):
function()
end= time.clock()
time= (end-start)/1000
如果函数的运行时间接近时钟精度,则非常不准确会受到测量偏差的影响。大多数测量时间仅仅是0到几个时钟周期之间的随机数。
根据您的系统工作负载,您从单个函数中观察到的“时间”可能完全是操作系统调度和其他无法控制的开销的假象。
第二个版本(不太准确)具有较少的测量偏差。如果您的功能非常快,您可能需要运行10,000次以阻止操作系统调度和其他开销。
当然,两者都是非常误导的。程序的运行时间 - 作为一个整体 - 不是函数运行时间的总和。您只能使用这些数字进行相对比较。它们不是传达意义的绝对测量。
答案 4 :(得分:14)
如果你想对一个python方法计时,即使你测量的块可能会抛出,一个好的方法是使用with
语句。将一些Timer
类定义为
import time
class Timer:
def __enter__(self):
self.start = time.clock()
return self
def __exit__(self, *args):
self.end = time.clock()
self.interval = self.end - self.start
然后你可能想要计时可能抛出的连接方法。使用
import httplib
with Timer() as t:
conn = httplib.HTTPConnection('google.com')
conn.request('GET', '/')
print('Request took %.03f sec.' % t.interval)
即使连接请求发生,也会调用 __exit()__
方法。更确切地说,您可以使用try
finally
查看结果,以防投诉,例如
try:
with Timer() as t:
conn = httplib.HTTPConnection('google.com')
conn.request('GET', '/')
finally:
print('Request took %.03f sec.' % t.interval)
答案 5 :(得分:7)
这更整洁
from contextlib import contextmanager
import time
@contextmanager
def timeblock(label):
start = time.clock()
try:
yield
finally:
end = time.clock()
print ('{} : {}'.format(label, end - start))
with timeblock("just a test"):
print "yippee"
答案 6 :(得分:4)
与@ AlexMartelli的回答类似
import timeit
timeit.timeit(fun, number=10000)
可以做到这一点。