使用Python';从程序中调用“timeit”,但其功能与命令行相同?

使用Python';从程序中调用“timeit”,但其功能与命令行相同?,python,timeit,Python,Timeit,例如: 但是请注意,只有在使用命令行界面时,timeit才会自动确定重复次数 有没有一种方法可以从Python脚本中调用它并自动确定重复次数,只返回最短的次数?当您从命令行调用timeit时,如下所示: python -mtimeit -s'import test' 'test.foo()' import timeit import utils_timeit as UT def foo(): total = 0 for i in range(10000): t

例如:

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


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

当您从命令行调用
timeit
时,如下所示:

python -mtimeit -s'import test' 'test.foo()'
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)
timeit
模块被称为脚本。特别是调用
main
函数:

if __name__ == "__main__":
    sys.exit(main())
如果查看,您将看到
main
函数可以采用
args
参数:

def main(args=None):    
    if args is None:
        args = sys.argv[1:]
因此,确实可以在程序中运行
timeit
,其行为与从CLI运行时所看到的完全相同。只需提供您自己的
args
,而不允许将其设置为
sys.argv[1://code>:

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
打印到控制台,而不是返回每个循环的时间。因此,如果您希望以编程方式使用结果,最简单的方法可能是先复制然后修改它——将打印代码改为返回
usec


OP示例: 如果您将其放入
utils\u 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

从Python3.6开始,对象有一个函数,该函数公开了命令行执行时如何确定
number

是的,这看起来不错,只是将
os.curdir
插入
sys.path
不应该是该函数的工作。PYTHONPATH应该正确设置,或者它应该是调用脚本(不是此函数)处理
sys.path
的工作。您的示例对我不起作用(
ImportError:cannotimportname foo
),但是
UT.timeit_auto(lambda:foo())
会产生类似于IPython的
timeit foo()的输出
@endolith:哦,但是lambda增加了一些开销,所以不太理想
lambda:5*5
为86纳秒,
5*5
为21纳秒。@endolith:您是从命令行调用脚本吗?e、 g.
python/path/to/script.py
?不,我是在Spyder中使用runfile()启动它的。你说得对,如果我在命令行上运行它,它就会工作。另外,我刚刚意识到IPython,这就是为什么IPython只对非常慢的函数执行1个循环,而timeit.main()的最小值是10个循环。timeit现在有一个函数