• functools.lru_cache装饰器


    functools.lru_cache装饰器

    functools.lru_cache是非常实用的装饰器,他实现了备忘功能它把耗时的函数的结果保存起来,避免传入相同的参数时重复计算。LRU是Least Recently Used的缩写,表明缓存不会无限制增长,一段时间不用的缓存条目会被扔掉。

    使用递归来生成斐波那契的第n个数

    # clock 装饰器
    import time
    import functools
    
    
    def clock(func):
        @functools.wraps(func)
        def clocked(*args, **kwargs):
            t0 = time.time()
            result = func(*args, **kwargs)
            elapsed = time.time() - t0
            name = func.__name__
            arg_lst = []
            if args:
                arg_lst.append(', '.join(repr(arg) for arg in args))
            if kwargs:
                pairs = ['%s=%r' % (k, w) for k, w in sorted(kwargs.items())]
                arg_lst.append(', '.join(pairs))
            arg_str = ', '.join(arg_lst)
            print('[%0.8fs] %s(%s) -> %r ' % (elapsed, name, arg_str, result))
            return result
        return clocked
    
    
    # 利用递归方式生成斐波那契
    @clock
    def fibonacci(n):
        if n < 2:
            return n
        return fibonacci(n - 2) + fibonacci(n - 1)
    
    
    if __name__ == '__main__':
        print(fibonacci(6))
        
    '''
    [0.00000000s] fibonacci(0) -> 0 
    [0.00000000s] fibonacci(1) -> 1 
    [0.00081015s] fibonacci(2) -> 1 
    [0.00000000s] fibonacci(1) -> 1 
    [0.00000000s] fibonacci(0) -> 0 
    [0.00000000s] fibonacci(1) -> 1 
    [0.00000000s] fibonacci(2) -> 1 
    [0.00000000s] fibonacci(3) -> 2 
    [0.00081015s] fibonacci(4) -> 3 
    [0.00000000s] fibonacci(1) -> 1 
    [0.00000000s] fibonacci(0) -> 0 
    [0.00000000s] fibonacci(1) -> 1 
    [0.00000000s] fibonacci(2) -> 1 
    [0.00081134s] fibonacci(3) -> 2 
    [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.00000000s] fibonacci(3) -> 2 
    [0.00000000s] fibonacci(4) -> 3 
    [0.00081134s] fibonacci(5) -> 5 
    [0.00162148s] fibonacci(6) -> 8 
    8
    '''
    

    可以看出使用递归会进行很多重复的计算,数据量增多时调用和计算更多。

    使用functools.lru_cache优化

    # clock 装饰器
    import time
    import functools
    
    
    def clock(func):
        @functools.wraps(func)
        def clocked(*args, **kwargs):
            t0 = time.time()
            result = func(*args, **kwargs)
            elapsed = time.time() - t0
            name = func.__name__
            arg_lst = []
            if args:
                arg_lst.append(', '.join(repr(arg) for arg in args))
            if kwargs:
                pairs = ['%s=%r' % (k, w) for k, w in sorted(kwargs.items())]
                arg_lst.append(', '.join(pairs))
            arg_str = ', '.join(arg_lst)
            print('[%0.8fs] %s(%s) -> %r ' % (elapsed, name, arg_str, result))
            return result
        return clocked
    
    
    # 利用递归方式生成斐波那契
    @functools.lru_cache()
    @clock
    def fibonacci(n):
        if n < 2:
            return n
        return fibonacci(n - 2) + fibonacci(n - 1)
    
    
    if __name__ == '__main__':
        print(fibonacci(6))
        
    '''
    [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 
    [0.00000000s] fibonacci(5) -> 5 
    [0.00000000s] fibonacci(6) -> 8 
    8
    '''
    

    可以看到使用lru_cache性能会显著改善。需要注意的是被lru_cache装饰的函数接受的参数必须是不可变类型。

  • 相关阅读:
    python字符串
    Python问题:SyntaxError: Non-ASCII character 'xe2' in file
    windows 运行库与dll文件
    sublime python 配置内容
    sublime ctrl b突然不能用解决方法
    c++ primer 的 textquery 例子。
    虚函数表
    理解各种数据类型和简单类在内存中的存在形式。
    最短路径纯贪心算法。
    中缀表达式生成二叉树
  • 原文地址:https://www.cnblogs.com/liao-lin/p/10855288.html
Copyright © 2020-2023  润新知