Python时间测量function
我想创build一个python函数来testing在每个函数中花费的时间,并用它的时间打印它的名字,我如何打印函数名,如果还有其他的方法,请告诉我
def measureTime(a): start = time.clock() a() elapsed = time.clock() elapsed = elapsed - start print "Time spent in (function name) is: ", elapsed
首先,我强烈build议使用分析器或至less使用timeit 。
但是,如果你想严格按照自己的时间方法来学习,那么在这里就可以开始使用装饰器了。
def timing(f): def wrap(*args): time1 = time.time() ret = f(*args) time2 = time.time() print '%s function took %0.3f ms' % (f.func_name, (time2-time1)*1000.0) return ret return wrap
而且用法很简单,只需使用@timing装饰器:
@timing def do_work(): #code
注意我调用f.func_name
来获取函数名称作为string(在Python 2中),或者f.__name__
在Python 3中。
在使用timeit
模块后,我不喜欢它的接口,与以下两种方法相比,它并不那么优雅。
以下代码在Python 3中。
装饰者方法
这与@ Mike的方法几乎是一样的。 在这里,我添加kwargs
和functools
包装,使其更好。
def timeit(func): @functools.wraps(func) def newfunc(*args, **kwargs): startTime = time.time() func(*args, **kwargs) elapsedTime = time.time() - startTime print('function [{}] finished in {} ms'.format( func.__name__, int(elapsedTime * 1000))) return newfunc @timeit def foobar(): mike = Person() mike.think(30)
上下文pipe理器方法
from contextlib import contextmanager @contextmanager def timeit_context(name): startTime = time.time() yield elapsedTime = time.time() - startTime print('[{}] finished in {} ms'.format(name, int(elapsedTime * 1000)))
例如,你可以像这样使用它:
with timeit_context('My profiling code'): mike = Person() mike.think()
with
块内的代码将被定时。
结论
使用第一种方法,你可以注释掉装饰器来获得正常的代码。 但是,它只能计时一个function。 如果你有一部分代码你不能做它的function,那么你可以select第二种方法。
例如,现在你有
images = get_images() bigImage = ImagePacker.pack(images, width=4096) drawer.draw(bigImage)
现在你想要的时间bigImage = ...
线。 如果你改变它的function,它将是:
images = get_images() bitImage = None @timeit def foobar(): nonlocal bigImage bigImage = ImagePacker.pack(images, width=4096) drawer.draw(bigImage)
看起来不是那么好…如果你在Python 2中,没有nonlocal
关键字。
相反,使用第二种方法非常适合:
images = get_images() with timeit_context('foobar'): bigImage = ImagePacker.pack(images, width=4096) drawer.draw(bigImage)
我没有看到timeit
模块的问题是什么。 这可能是最简单的方法。
import timeit timeit.timeit(a, number=1)
它也可以发送参数给函数。 所有你需要的是使用装饰器来包装你的function。 更多解释在这里: http : //www.pythoncentral.io/time-a-python-function/
你可能有兴趣编写自己的定时语句的唯一情况是,如果你只想运行一次函数,也想获得它的返回值。
使用timeit
模块的好处是它可以让你重复执行的次数。 这可能是必要的,因为其他进程可能会影响您的定时精度。 所以,你应该多次运行,看看最低的价值。
使用这样的分析器,而不是试图通过你自己来实现这样的function。
Timeit有两个很大的缺陷:它不返回函数的返回值,它使用eval,它需要传入额外的导入设置代码。 这简单而优雅地解决了这两个问题:
def timed(f): start = time.time() ret = f() elapsed = time.time() - start return ret, elapsed timed(lambda: database.foo.execute('select count(*) from source.apachelog')) (<sqlalchemy.engine.result.ResultProxy object at 0x7fd6c20fc690>, 4.07547402381897)
使用装饰器的装饰器方法Python库:
import decorator @decorator def timing(func, *args, **kwargs): '''Function timing wrapper Example of using: ``@timing()`` ''' fn = '%s.%s' % (func.__module__, func.__name__) timer = Timer() with timer: ret = func(*args, **kwargs) log.info(u'%s - %0.3f sec' % (fn, timer.duration_in_seconds())) return ret
在我的博客上查看post:
发布在mobilepro.pl博客
我在谷歌加上的职位
有一个简单的时间工具。 https://github.com/RalphMao/PyTimer
它可以像装饰者一样工作:
from pytimer import Timer @Timer(average=False) def matmul(a,b, times=100): for i in range(times): np.dot(a,b)
输出:
matmul:0.368434 matmul:2.839355
它也可以像命名空间控制的插件计时器一样工作(如果你将它插入到一个有很多代码的函数中,并且可以在其他地方调用),它是很有用的。
timer = Timer() def any_function(): timer.start() for i in range(10): timer.reset() np.dot(np.ones((100,1000)), np.zeros((1000,500))) timer.checkpoint('block1') np.dot(np.ones((100,1000)), np.zeros((1000,500))) np.dot(np.ones((100,1000)), np.zeros((1000,500))) timer.checkpoint('block2') np.dot(np.ones((100,1000)), np.zeros((1000,1000))) for j in range(20): np.dot(np.ones((100,1000)), np.zeros((1000,500))) timer.summary() for i in range(2): any_function()
输出:
========Timing Summary of Default Timer======== block2:0.065062 block1:0.032529 ========Timing Summary of Default Timer======== block2:0.065838 block1:0.032891
希望它会有所帮助
我的做法是:
from time import time def printTime(start): end = time() duration = end - start if duration < 60: return "used: " + str(round(duration, 2)) + "s." else: mins = int(duration / 60) secs = round(duration % 60, 2) if mins < 60: return "used: " + str(mins) + "m " + str(secs) + "s." else: hours = int(duration / 3600) mins = mins % 60 return "used: " + str(hours) + "h " + str(mins) + "m " + str(secs) + "s."
在执行函数/循环之前设置一个variables为start = time()
在块之后执行printTime(start)
。
你得到了答案。