在Python中测量带参数的函数执行时间

2 投票
5 回答
7022 浏览
提问于 2025-04-15 17:24

我正在尝试测量raw_queries(...)的执行时间,但到现在为止都没有成功。我发现应该使用timeit模块。问题是我不知道怎么从环境中把参数传递给这个函数。

重要提示:在调用raw_queries之前,我们必须先执行phase2()(环境初始化)。

附带说明:这段代码是用Python 3写的。

def raw_queries(queries, nlp):
    """ Submit queries without getting visual response """

    for q in queries:
        nlp.query(q)

def evaluate_queries(queries, nlp):
    """ Measure the time that the queries need to return their results """

    t = Timer("raw_queries(queries, nlp)", "?????")
    print(t.timeit())

def phase2():
    """ Load dictionary to memory and subsequently submit queries """

    # prepare Linguistic Processor to submit it the queries
    all_files = get_files()
    b = LinguisticProcessor(all_files)
    b.loadDictionary()

    # load the queries
    queries_file = 'queries.txt'
    queries = load_queries(queries_file)

if __name__ == '__main__':
    phase2()

谢谢大家的帮助。

更新:我们可以通过Timer的第二个参数来调用phase2()。问题是我们需要从环境中获取参数(queries, nlp)

更新:到目前为止,最好的解决方案是得到unutbu的帮助(这里只列出了变化的部分):

def evaluate_queries():
    """ Measure the time that the queries need to return their results """

    t = Timer("main.raw_queries(queries, nlp)", "import main;\
        (queries,nlp)=main.phase2()")

    sf = 'Execution time: {} ms'
    print(sf.format(t.timeit(number=1000)))


def phase2():
    ...

    return queries, b


def main():
    evaluate_queries()

if __name__ == '__main__':
    main()

5 个回答

2

自定义计时器函数可能是一个解决方案:

import time

def timer(fun,*args):
    start = time.time()
    ret = fun(*args)
    end = time.time()
    return (ret, end-start)

使用方法如下:

>>> from math import sin
>>> timer(sin, 0.5)
(0.47942553860420301, 6.9141387939453125e-06)

这意味着 sin 函数返回了 0.479...,而且它花费了 6.9e-6 秒。确保你的函数运行的时间足够长,这样才能得到可靠的数字(不要像上面的例子那样)。

2

通常情况下,你会使用 timeit 这个工具。

你可以在 这里这里 找到一些例子。

另外要注意:

默认情况下,timeit() 在计时的时候会暂时关闭垃圾回收。这种做法的好处是可以让不同的计时结果更具可比性。但缺点是,垃圾回收可能是被测函数性能的重要因素。

或者你也可以使用 time 模块自己写一个定制的计时器。

如果你选择自定义计时器,记得在Windows上使用 time.clock(),而在其他平台上使用 time.time()。 (timeit内部会自动选择)

import sys
import time

# choose timer to use
if sys.platform.startswith('win'):
    default_timer = time.clock
else:
    default_timer = time.time

start = default_timer()
# do something
finish = default_timer()
elapsed = (finish - start)
6

首先,千万不要用时间模块来测量函数的执行时间。这很容易导致错误的结论。你可以看看这个链接 timeit和时间装饰器的对比,里面有个例子。

测量函数执行时间最简单的方法是使用IPython的 %timeit 命令。在这里,你只需要启动一个交互式的IPython会话,调用 phase2(),定义 queries,然后运行

%timeit raw_queries(queries,nlp)

我知道的第二简单的方法是从命令行调用timeit:

python -mtimeit -s"import test; queries=test.phase2()" "test.raw_queries(queries)"

(在上面的命令中,我假设脚本叫 test.py

这里的用法是

python -mtimeit -s"SETUP_COMMANDS" "COMMAND_TO_BE_TIMED"

为了能够把 queries 传递给 raw_queries 函数调用,你需要先定义 queries 这个变量。在你发的代码中,queries 是在 phase2() 中定义的,但只是局部的。所以为了把 queries 设置为全局变量,你需要让 phase2 返回 queries

def phase2():
    ...
    return queries

如果你不想这样搞乱 phase2,可以创建一个虚拟函数:

def phase3():
    # Do stuff like phase2() but return queries
    return queries

撰写回答