【问题标题】:Huge difference in process timing of functions (timit, time)函数的处理时间差异巨大(时间、时间)
【发布时间】: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


【解决方案1】:

您从不调用 mycode 中的函数,因此您只需要计算定义函数所需的时间(我希望这会很快)。

你需要调用函数:

import timeit

mycode = ''' 
def fact1(n):
    if n == 0:
        return 1
    else:
        return n * fact1(n-1)

fact1(100000)
'''

print(timeit.timeit(stmt=mycode, number=100000) / 100000)

实际上,这是次优的,因为您将定义包含在时间安排中。我会改变它并传递一个函数:

def fact1(n):
    if n == 0:
        return 1
    else:
        return n * fact1(n-1) 

print(timeit.timeit(lambda: fact1(100000), number=100000) / 100000)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    • 2021-02-18
    • 1970-01-01
    相关资源
    最近更新 更多