Python时间度量函数

2024-04-18 23:26:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个python函数来测试在每个函数中花费的时间,并用它的时间打印它的名称,如何打印函数名称,如果有其他方法可以打印,请告诉我

def measureTime(a):
    start = time.clock() 
    a()
    elapsed = time.clock()
    elapsed = elapsed - start
    print "Time spent in (function name) is: ", elapsed

Tags: 方法函数in名称timedef时间start
3条回答

在玩了timeit模块之后,我不喜欢它的接口,与下面两种方法相比,它不是那么优雅。

以下代码在Python3中。

装饰方法

这与@Mike的方法几乎相同。在这里我添加了kwargsfunctoolswrap以使其更好。

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块中的代码将被计时。

结论

使用第一个方法,您可以完全注释掉decorator以获得正常代码。但是,它只能计时一个函数。如果代码的某个部分不知道如何使其成为函数,则可以选择第二种方法。

例如,现在

images = get_images()
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)

现在您要计时bigImage = ...行。如果您将其更改为函数,它将是:

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)

也可以向函数发送参数。您只需要使用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__

相关问题 更多 >