首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python时间度量函数

Python时间度量函数
EN

Stack Overflow用户
提问于 2011-03-30 04:12:40
回答 8查看 209.5K关注 0票数 134

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

代码语言:javascript
复制
def measureTime(a):
    start = time.clock() 
    a()
    elapsed = time.clock()
    elapsed = elapsed - start
    print "Time spent in (function name) is: ", elapsed
EN

回答 8

Stack Overflow用户

发布于 2014-01-05 01:27:05

玩过timeit模块后,我不喜欢它的界面,与以下两种方法相比,它并不那么优雅。

下面的代码是Python 3编写的。

装饰器方法

这与@Mike的方法几乎是一样的。在这里,我添加了kwargsfunctools wrap以使其更好。

代码语言:javascript
复制
def timeit(func):
    @functools.wraps(func)
    def new_func(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        elapsed_time = time.time() - start_time
        print('function [{}] finished in {} ms'.format(
            func.__name__, int(elapsed_time * 1_000)))
        return result
    return new_func

@timeit
def foobar():
    mike = Person()
    mike.think(30)

上下文管理器方法

代码语言:javascript
复制
from contextlib import contextmanager

@contextmanager
def timeit_context(name):
    start_time = time.time()
    yield
    elapsed_time = time.time() - start_time
    print('[{}] finished in {} ms'.format(name, int(elapsed_time * 1_000)))

例如,您可以像这样使用它:

代码语言:javascript
复制
with timeit_context('My profiling code'):
    mike = Person()
    mike.think()

并且with块内的代码将被计时。

结论

使用第一种方法,您可以很容易地注释掉装饰器以获得正常的代码。但是,它只能对函数计时。如果你有一部分代码,你不知道怎么把它变成一个函数,那么你可以选择第二种方法。

例如,现在你有

代码语言:javascript
复制
images = get_images()
big_image = ImagePacker.pack(images, width=4096)
drawer.draw(big_image)

现在,您需要对big_image = ...行进行计时。如果您将其更改为函数,则它将为:

代码语言:javascript
复制
images = get_images()
big_image = None
@timeit
def foobar():
    nonlocal big_image
    big_image = ImagePacker.pack(images, width=4096)
drawer.draw(big_image)

如果你在没有nonlocal关键字的Python2中,看起来就不那么great...What了。

相反,使用第二种方法非常适合这里:

代码语言:javascript
复制
images = get_images()
with timeit_context('foobar'):
    big_image = ImagePacker.pack(images, width=4096)
drawer.draw(big_image)
票数 59
EN

Stack Overflow用户

发布于 2014-07-02 01:48:19

我不知道timeit模块有什么问题。这可能是最简单的方法。

代码语言:javascript
复制
import timeit
timeit.timeit(a, number=1)

也可以向函数发送参数。你所需要的就是使用装饰器来包装你的函数。更多解释在这里:http://www.pythoncentral.io/time-a-python-function/

您可能对编写自己的计时语句感兴趣的唯一情况是,如果您希望一个函数只运行一次,并且还希望获得它的返回值。

使用timeit模块的优点是,它允许您repeat执行的次数。这可能是必要的,因为其他进程可能会干扰您的计时准确性。因此,您应该多次运行它,并查看最低值。

票数 12
EN

Stack Overflow用户

发布于 2015-02-05 06:06:35

Timeit有两个大缺陷:它不返回函数的返回值,它使用eval,这需要为导入传入额外的设置代码。这简单而优雅地解决了这两个问题:

代码语言:javascript
复制
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)
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5478351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档