Python functools.lru_cache实现函数结果缓存功能

这是一项优化技术,把耗时的函数的结果保存起来,避免了传入相同的参数时重复计算。

lru是Least Recently Used的缩写,表明缓存不会无限制增长,一段时间不用的缓存条目会被扔掉。

 

生成第n个斐波那契数列,这种慢速递归函数非常适合使用lru_cache。

 斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

示例,生成第n个斐波那契数列

import time
import functools


def clock(func):
    """函数执行时间,参数,结果"""

    @functools.wraps(func)
    def inner(*args, **kwargs):
        t0 = time.time()
        result = func(*args, **kwargs)
        time_use = time.time() - t0
        func_name = func.__name__
        parameter = []
        if args:
            parameter.append(','.join(repr(arg) for arg in args))
        if kwargs:
            kwargs_str = ",".join('%s=%r' % (k, v) for k, v in kwargs.items())
            parameter.append(kwargs_str)
        parameter = ','.join(parameter)
        print('[%0.8fs] %s(%s) -> %r' % (time_use, func_name, parameter, result))
        return result

    return inner


@clock
def fibonacci(n):
    """计算斐波那契数列的第n个项(从0项开始)"""
    if n < 2:
        return n
    return fibonacci(n - 2) + fibonacci(n - 1)


print(fibonacci(4))
打印
[0.00000000s] fibonacci(0) -> 0
[0.00000000s] fibonacci(1) -> 1
[0.00000000s] fibonacci(2) -> 1
[0.00000000s] fibonacci(1) -> 1
[0.00000000s] fibonacci(0) -> 0
[0.00000000s] fibonacci(1) -> 1
[0.00000000s] fibonacci(2) -> 1
[0.00100422s] fibonacci(3) -> 2
[0.00100422s] fibonacci(4) -> 3
3

可以看到,浪费时间的地方很明显,fibonacci(1)的运算调用了三次,如果使用lru_cache装饰后,性能会显著改善。

@functools.lru_cache()
@clock
def fibonacci(n):
    """计算斐波那契数列的第n个项(从0项开始)"""
    if n < 2:
        return n
    return fibonacci(n - 2) + fibonacci(n - 1)


print(fibonacci(4))
打印
[0.00000000s] fibonacci(0) -> 0
[0.00000000s] fibonacci(1) -> 1
[0.00000000s] fibonacci(2) -> 1
[0.00000000s] fibonacci(3) -> 2
[0.00000000s] fibonacci(4) -> 3
3

每个n值值调用了一次函数,因为重复的调用会在缓存中取,不再真实的调用。

 

lru_cache可以使用两个可选的参数。lru_cache(maxsize=128, typed=False)

maxsize 表示存储多少个调用的结果。

typed 如果设置为True,会把不同的类型分开存储,比如说通常认为1.0和1是一样的结果,但是他们类型不同,一个是浮点数,一个数整数。

 

ps:因为lru_cache使用字典存储结果,键值是根据调用时传入的参数来创建的,所有被装饰的函数的参数,必须是可散列的。

你可能感兴趣的:(流畅的Python读书笔记,python)