在程序中使用Python的"timeit",但功能与命令行相同? [英] Use Python's `timeit` from a program but functioning the same way as the command line?

查看:121
本文介绍了在程序中使用Python的"timeit",但功能与命令行相同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,文档说:

但是请注意,只有在使用命令行界面时,timeit才会自动确定重复次数.

Note however that timeit will automatically determine the number of repetitions only when the command-line interface is used.

有没有一种方法可以在Python脚本中调用它,并自动确定重复次数,而只返回最短的次数?

Is there a way to call it from within a Python script and have the number of repetitions be determined automatically, with only the shortest number returned?

推荐答案

从命令行中像这样调用timeit时:

When you call timeit from the command line like this:

python -mtimeit -s'import test' 'test.foo()'

timeit模块被称为脚本.特别地,main函数称为:

The timeit module is called as a script. In particular, the main function is called:

if __name__ == "__main__":
    sys.exit(main())

如果您查看源代码,您会看到main函数可以接受args自变量:

If you look at the source code, you'll see that the main function can take an args argument:

def main(args=None):    
    if args is None:
        args = sys.argv[1:]

因此,确实可以从程序中运行timeit,其行为与从CLI运行时所看到的行为完全相同.只需提供自己的args而不是将其设置为sys.argv[1:]:

So indeed it is possible to run timeit from within a program with exactly the same behavior as you see when run from the CLI. Just supply your own args instead of allowing it to be set to sys.argv[1:]:

import timeit
import shlex

def foo():
    total = 0
    for i in range(10000):
        total += i**3
    return total

timeit.main(args=shlex.split("""-s'from __main__ import foo' 'foo()'"""))

将打印类似

100 loops, best of 3: 7.9 msec per loop


不幸的是,main打印到控制台,而不是返回每个循环的时间.因此,如果您要以编程方式使用结果,最简单的方法可能是从复制 main函数,然后对其进行修改-更改打印代码以改为返回usec.


Unfortunately, main prints to the console, instead of returning the time per loop. So if you want to programmatically use the result, perhaps the easiest way would be to start by copying the main function and then modifying it -- changing the printing code to instead return usec.

OP的示例: 如果将其放置在utils_timeit.py中:

Example by OP: If you place this in utils_timeit.py:

import timeit
def timeit_auto(stmt="pass", setup="pass", repeat=3):
    """
    http://stackoverflow.com/q/19062202/190597 (endolith)
    Imitate default behavior when timeit is run as a script.

    Runs enough loops so that total execution time is greater than 0.2 sec,
    and then repeats that 3 times and keeps the lowest value.

    Returns the number of loops and the time for each loop in microseconds
    """
    t = timeit.Timer(stmt, setup)

    # determine number so that 0.2 <= total time < 2.0
    for i in range(1, 10):
        number = 10**i
        x = t.timeit(number) # seconds
        if x >= 0.2:
            break
    r = t.repeat(repeat, number)
    best = min(r)
    usec = best * 1e6 / number
    return number, usec

您可以在如下脚本中使用它:

you can use it in scripts like this:

import timeit
import utils_timeit as UT

def foo():
    total = 0
    for i in range(10000):
        total += i**3
    return total

num, timing = UT.timeit_auto(setup='from __main__ import foo', stmt='foo()')
print(num, timing)

这篇关于在程序中使用Python的"timeit",但功能与命令行相同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆