【发布时间】:2020-05-16 19:55:09
【问题描述】:
出于一些教学目的,我想测量一些函数的时间(比所示函数稍微复杂一些),并稍后讨论大 O 缩放行为。但我对生成的数字的可靠性有疑问:
我的代码:
import time
import numpy as np
def run_time(fun, runs):
times = []
for i in range(runs):
t0 = time.clock()
fun()
t1 = time.clock() - t0
times.append(t1)
return np.mean(times), np.std(times)#, times
def fact0(n):
product = 1
for i in range(n):
product = product * (i+1)
return product
def fact1(n):
if n == 0:
return 1
else:
return n * fact1(n-1)
print(run_time(lambda: fact0(500), 100000))
print(run_time(lambda: fact1(500), 100000))
我通常会得到类似的东西:
(0.000186065330000082, 5.08689027009196e-05)
(0.0002853808799999845, 8.285739309454826e-05)
所以标准差大于平均值。这对我来说太可怕了。此外,由于没有递归,我预计 fact0() 比 fact1() 快得多。
如果我现在使用 timeit:
import timeit
mysetup = ""
mycode = '''
def fact1(n):
if n == 0:
return 1
else:
return n * fact1(n-1)
fact1(500)
'''
print(timeit.timeit(setup = mysetup, stmt = mycode, number = 100000)/100000)
我会得到一些差不多 magnt的东西。平均值较小:
2.463713497854769e-07
经过以下讨论的更正后是:
0.00028513264190871266
这与run_time版本非常吻合。
所以我的问题是如何适当地计时功能?为什么我的两种获取时间的方法之间存在巨大差异?有什么建议吗?我很想坚持使用“time.clock()”并且我不想使用(再次出于教学原因)cProfile 甚至更复杂的模块。
感谢任何 cmets...
(由@Carcigenicate 由cmets 编辑)
【问题讨论】:
-
错字?你永远不会在
run_time中调用fun。 -
不是吗?在 t0 = time.clock() 和 t1 = time.clock() - t0 之间的 run_time 的第 5 行。这不正确吗?不过,该函数已执行。
-
您需要
fun()。只是fun不会调用它。 -
等等,你在把它交给
run_time之前调用了一次函数。您需要传递函数本身,例如run_time(fact0, 10000)。现在,run_time无所事事 100,000 次。您需要将其包装在 lambda 或其他东西中以提供参数。像run_time(lambda: fact0(500, 10000)这样的东西。解决这两个问题,然后重试。 -
你永远不会调用
mycode中的函数。您只是在计算定义函数所需的时间。
标签: python-3.x function time