2024-04-18 23:26:23 发布
网友
我想创建一个python函数来测试在每个函数中花费的时间,并用它的时间打印它的名称,如何打印函数名称,如果有其他方法可以打印,请告诉我
def measureTime(a): start = time.clock() a() elapsed = time.clock() elapsed = elapsed - start print "Time spent in (function name) is: ", elapsed
在玩了timeit模块之后,我不喜欢它的接口,与下面两种方法相比,它不是那么优雅。
timeit
以下代码在Python3中。
这与@Mike的方法几乎相同。在这里我添加了kwargs和functoolswrap以使其更好。
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)
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块中的代码将被计时。
with
使用第一个方法,您可以完全注释掉decorator以获得正常代码。但是,它只能计时一个函数。如果代码的某个部分不知道如何使其成为函数,则可以选择第二种方法。
例如,现在
images = get_images() bigImage = ImagePacker.pack(images, width=4096) drawer.draw(bigImage)
现在您要计时bigImage = ...行。如果您将其更改为函数,它将是:
bigImage = ...
images = get_images() bitImage = None @timeit def foobar(): nonlocal bigImage bigImage = ImagePacker.pack(images, width=4096) drawer.draw(bigImage)
看起来不太好…如果你在Python 2中,它没有nonlocal关键字怎么办。
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)
也可以向函数发送参数。您只需要使用decorators包装您的函数。更多说明如下:http://www.pythoncentral.io/time-a-python-function/
您可能对编写自己的计时语句感兴趣的唯一情况是,您希望只运行一次函数,并且还希望获得其返回值。
使用timeit模块的好处是,它允许您repeat执行的次数。这可能是必要的,因为其他进程可能会干扰您的计时精度。所以,您应该多次运行它并查看最低值。
首先,我强烈建议使用profiler或至少使用timeit。
然而,如果您想严格地编写自己的计时方法来学习,这里是开始使用decorator的地方。
Python2:
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 decorator:
@timing def do_work(): #code
Python3:
def timing(f): def wrap(*args): time1 = time.time() ret = f(*args) time2 = time.time() print('{:s} function took {:.3f} ms'.format(f.__name__, (time2-time1)*1000.0)) return ret return wrap
注意,我调用f.func_name以获取字符串形式的函数名(在Python 2中),或者在Python 3中调用f.__name__。
f.func_name
f.__name__
在玩了
timeit
模块之后,我不喜欢它的接口,与下面两种方法相比,它不是那么优雅。以下代码在Python3中。
装饰方法
这与@Mike的方法几乎相同。在这里我添加了
kwargs
和functools
wrap以使其更好。上下文管理器方法
例如,您可以像这样使用它:
并且
with
块中的代码将被计时。结论
使用第一个方法,您可以完全注释掉decorator以获得正常代码。但是,它只能计时一个函数。如果代码的某个部分不知道如何使其成为函数,则可以选择第二种方法。
例如,现在
现在您要计时
bigImage = ...
行。如果您将其更改为函数,它将是:看起来不太好…如果你在Python 2中,它没有
nonlocal
关键字怎么办。相反,使用第二种方法非常适合这里:
我不知道
timeit
模块有什么问题。这可能是最简单的方法。也可以向函数发送参数。您只需要使用decorators包装您的函数。更多说明如下:http://www.pythoncentral.io/time-a-python-function/
您可能对编写自己的计时语句感兴趣的唯一情况是,您希望只运行一次函数,并且还希望获得其返回值。
使用
timeit
模块的好处是,它允许您repeat执行的次数。这可能是必要的,因为其他进程可能会干扰您的计时精度。所以,您应该多次运行它并查看最低值。首先,我强烈建议使用profiler或至少使用timeit。
然而,如果您想严格地编写自己的计时方法来学习,这里是开始使用decorator的地方。
Python2:
用法很简单,只需使用@timing decorator:
Python3:
注意,我调用
f.func_name
以获取字符串形式的函数名(在Python 2中),或者在Python 3中调用f.__name__
。相关问题 更多 >
编程相关推荐