【发布时间】:2021-08-23 19:54:01
【问题描述】:
魔术命令%timeit 不是在脚本中使用的。
在Use Python's `timeit` from a program but functioning the same way as the command line?中,用户Unutbu提出了以下功能:
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)
这是一个非常聪明和方便的解决方案。但是,我正在寻找更好的方法。我不想给函数一个setup 声明,我认为这很讨厌。如果我有一个数据框df 和一个列名column_name_a,我不想在我想为df[column_name_a] 计时操作时明确声明setup='from __main__ import df, column_name_a'。
有什么好的方法可以解决吗?我自己通过将它添加到函数中来完成它,以便通过捕获错误将所有需要的变量添加到循环中的 setup 语句中:
condition = True
setup = 'from __main__ import _'
while condition:
try:
t = timeit.Timer(stmt, setup)
t.repeat(repeat, number)
condition = False
except NameError as err:
str_err = str(err)
extra_import = str_err.split(sep="'")[1]
setup = setup + ', ' + extra_import
这当然不是一个非常微妙的解决方案。有没有人有更好的方法?
此外,在同一个线程(Use Python's `timeit` from a program but functioning the same way as the command line?)中,有人提议使用Timer.autorange 方法。我不确定如何将其包含在函数中。谁能帮我解决这个问题?
【问题讨论】: