zoukankan      html  css  js  c++  java
  • 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装饰的函数接受的参数必须是不可变类型。

  • 相关阅读:
    参加“51testing第70期深圳技术沙龙”感想
    软件测试的实质
    JMeter使用技巧
    一个软件测试员的工作与学习(二)
    JMeter基础之元件的作用域与执行顺序
    测试之美测试员的心思你不懂
    博客搬家的原因与文章被转的看法
    ubuntu下配置java环境
    敏捷软件测试初见
    软件测试人员分工
  • 原文地址:https://www.cnblogs.com/liao-lin/p/10855288.html
Copyright © 2011-2022 走看看