例如,文档说:
但是请注意,只有在使用命令行界面时,timeit 才会自动确定重复次数。
有没有办法从 Python 脚本中调用它并自动确定重复次数,只返回最短的数字?
当您timeit
像这样从命令行调用时:
python -mtimeit -s'import test' 'test.foo()'
该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:]
:
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
然后对其进行修改——将打印代码更改为 return usec
。
OP的示例:
如果您将其放在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
你可以在这样的脚本中使用它:
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 3.6 开始,timeit.Timer
对象具有一个autorange
函数,该函数公开了如何number
确定命令行执行的方式。