Python中的记忆化--简单介绍

441 阅读4分钟

在本教程中,我们将讨论非常流行的优化技术之一--Python中的Memoization,主要用于加速计算机程序。那么,让我们开始吧


什么是Python中的备忘录化?

在计算机编程的世界里,Python中的Memoisation或Memoization是一种特殊的优化技术,主要用于加速我们的计算机程序。它通过将昂贵的(就运行时间而言)函数调用的结果存储到内存中,并在需要任何存储或缓存值时使用它,有效地减少了计算机程序的运行时间。

它确保一个特定的函数或方法不需要为同一组输入运行多次,因为结果已经可以作为缓存/存储的数据。

它类似于缓存,它涉及到基于其输入参数的函数的返回值的缓存。

在Python中,我们可以使用**函数和基于类的装饰器**在我们的程序中实现记忆化技术。在我们的整个讨论中,我们将使用一个递归的Python程序来计算第n个斐波那契数,因为对于更大的输入,这个程序会变得非常非常慢,因为对于相同的输入值,函数调用的数量会随着输入大小而增加。

在Python中使用基于函数的装饰器进行记忆化

这是在Python中实现记忆化技术的最好和最复杂的方法,对于那些想了解这种优化技术实际如何工作的人来说。在这种实现记忆化技术的方法中,我们在Python中定义我们自己的装饰器函数来缓存/存储函数调用的返回值。让我们来看看如何编写Python代码来实现这一点。

# Memoization using function-based decorators

def memoize(f):
    cache = {}
    def foo(x):
        if x not in cache:
            cache[x] = f(x)
        return cache[x]
    return foo

@memoize
def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)

# Driver code
fibonacci(20)

输出

6765

使用基于类的装饰器进行记忆化

这是在Python中实现记忆化技术的第二种最好的方法,也是最复杂的方法,对于想了解这种优化技术实际工作原理的初学者来说。在这种实现记忆化技术的方法中,我们在Python中定义自己的装饰器类来缓存/存储函数调用的返回值。让我们编写Python代码来实现这一点。

# Memoization using class-based decorators

class classMemoize:
    def __init__(self, f):
        self.f = f
        self.cache = {}
    def __call__(self, *x):
        if x not in self.cache:
            self.cache[x] = self.f(*x)
        return self.cache[x]

@classMemoize
def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)

# Driver code
fibonacci(50)

输出

12586269025

使用内置的装饰器函数进行记忆化

这是在Python中实现记忆化技术的一种简单和最容易的方法。

在这种实现记忆化技术的方法中,我们不定义我们自己的装饰函数或类,而是利用内置的函数如lru_cache()cache() 来缓存/存储一个函数调用的中间结果。

这些lru_cache()cache() 函数被定义在funtools 库中,它是一个标准的 Python 库,在正常的 Python 安装中都有。

lru_cache(maxsize=None, typed=False) 函数通过它的参数,如maxsizetyped ,提供了一些定制的功能。参数maxsize 决定是否启用LRU功能,设置其值为None或一个整数值。而参数typed 决定不同类型的数据是否被分开缓存。

一个整数值将限制Python程序执行过程中保持的缓存的大小,None值将禁用LRU功能,然后缓存可以不受任何约束地增长。

cache() 函数从Python 3.9版本开始可用,它等同于funtools 库中的lru_cache(maxsize=None) 函数。

# Memoization using built-in function

import functools

@functools.cache
def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)

# Driver code
fibonacci(100)

输出

354224848179261915075

总结

在本教程中,我们已经学会了如何使用函数和基于类的装饰器在Python中使用记忆化技术。我希望你已经很好地理解了上面讨论的内容,并准备在你的Python程序中使用/实现这种记忆化技术以提高其速度。