Python Memonization decorator的运行速度比原始函数慢

Python Memonization decorator的运行速度比原始函数慢,python,decorator,Python,Decorator,我在用斐波那契函数做记忆装饰练习。当输入变大时,memorized函数应该更快,因为它从字典返回结果,而不是再次计算结果 我正在使用timeit.timeit()测量函数的执行时间,并将其记录为on和off。 我得到的结果与我预期的完全相反。没有decorator的执行速度要快得多 # memorized decorator for fibonacci series def mem_fib(f): def wrapper(n): wrapper.d = {} # cre

我在用斐波那契函数做记忆装饰练习。当输入变大时,memorized函数应该更快,因为它从字典返回结果,而不是再次计算结果

我正在使用
timeit.timeit()
测量函数的执行时间,并将其记录为on和off。 我得到的结果与我预期的完全相反。没有decorator的执行速度要快得多

# memorized decorator for fibonacci series
def mem_fib(f):
    def wrapper(n):
        wrapper.d = {}  # create the attr member of THIS wrapper
        if n in wrapper.d:
            return wrapper.d[n]
        wrapper.d[n] = f(n)  # save f() return in a dict
        return wrapper.d[n]
    return wrapper

@mem_fib
def fibonacci(n):
    assert n >= 0
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
没有装饰师

我运行了多次timeit,我只把一个输出加起来。我错过了什么

谢谢

更新:多亏了丹尼尔的回答,我发现了我的错误。我将字典创建移到了包装器之外,结果要好得多

>>> print(timeit.timeit('decorators.fibonacci(10)', setup='import decorators'))
0.248986574759

每次调用函数时都会创建一个新字典,因为
wrapper
函数总是执行
wrapper.d={}
。因此,缓存将永远不会被填充,并且您的代码每次都有额外的创建字典的开销


该行应该在该函数之外,在您从
mem\u fib

返回它之前,每次调用该函数时,您都会创建一个新字典,因为您的
包装器
函数总是执行
包装器.d={}
。因此,缓存将永远不会被填充,并且您的代码每次都有额外的创建字典的开销


在您从
mem\u fib

返回之前,该行应该超出该函数的范围,您是否厌倦了它以获得更大的值?我的猜测是,对于7和10来说,记忆所带来的小开销比实际计算的成本要大。我想对于fibbonacci(100),它可能会产生预期的结果。这是因为您的assert语句吗?作为补充说明,您不需要在末尾使用pass语句。您可以检查负n,并引发错误,然后检查基本大小写并返回。如果两个检查都失败,那一定是递归的情况,因此不需要使用其他方法。Mai这个小小的更改使代码更易于阅读,谢谢你的注释。你对更大的值感到厌倦了吗?我的猜测是,对于7和10来说,记忆所带来的小开销比实际计算的成本要大。我想对于fibbonacci(100),它可能会产生预期的结果。这是因为您的assert语句吗?作为补充说明,您不需要在末尾使用pass语句。您可以检查负n,并引发错误,然后检查基本大小写并返回。如果两个检查都失败,那一定是递归的情况,因此不需要使用其他方法。Mai这个小小的更改使代码更易于阅读,谢谢你的注释我不知道我怎么会错过它,谢谢!当我将字典创建移到包装器之外(在mem_fib内部)时,结果与我预期的一样
print(timeit.timeit('decorators.fibonacci(10)”,setup('import decorators'))0.24898657574759
我不知道我怎么会错过它,谢谢!当我将字典创建移到包装器之外(在mem_fib内部)时,结果与我预期的一样
print(timeit.timeit('decorators.fibonacci(10)”,setup('import decorators'))0.24898657574759
>>> print(timeit.timeit('decorators.fibonacci(7)', setup='import decorators'))
5.10131571594
>>> print(timeit.timeit('decorators.fibonacci(10)', setup='import decorators'))
21.9784012801
>>> print(timeit.timeit('decorators.fibonacci(10)', setup='import decorators'))
0.248986574759