lru_cahce装饰器
2019-08-20 10:34 美丽的名字 阅读(165) 评论(0) 收藏 举报这个装饰器实现了备忘的功能,是一项优化技术,把耗时的函数的结果保存起来,避免传入相同的参数时重复计算。lru 是(least recently used)的缩写,即最近最少使用原则。表明缓存不会无限制增长,一段时间不用的缓存条目会被扔掉。
这个装饰器支持传入参数,还能有这种操作的?maxsize 是保存最近多少个调用的结果,最好设置为 2 的倍数,默认为 128。如果设置为 None 的话就相当于是 maxsize 为正无穷了。还有一个参数是 type,如果 type 设置为 true,即把不同参数类型得到的结果分开保存,如 f(3) 和 f(3.0) 会被区分开。
下面通过一个简单的测试验证下使用lru_chache装饰器和不使用这个装饰器的区别:
先定义一个追踪函数:
def track(func): @functools.wraps(func) def inner(*args): result = func(*args) print("{} --> ({}) --> {} ".format(func.__name__, args[0], result)) return result return inner
通常递归函数比较适合使用这个装饰器,就拿斐波那契数列测试:
不使用装饰器:
@track def fib(n): if n < 2: return n return fib(n - 2) + fib(n - 1)
使用装饰器:
@functools.lru_cache() @track def fib_with_cache(n): if n < 2: return n return fib_with_cache(n - 2) + fib_with_cache(n - 1)
不使用装饰器的结果:
fib(10) 调用了 177 次, 共花费了 0.007 秒
fib(10) 759 function calls (407 primitive calls) in 0.007 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.007 0.007 {built-in method builtins.exec} 1 0.000 0.000 0.007 0.007 decorator.py:1(<module>) 177/1 0.000 0.000 0.007 0.007 decorator.py:5(inner) 177/1 0.000 0.000 0.007 0.007 decorator.py:12(fib) 177 0.006 0.000 0.006 0.000 {built-in method builtins.print} 177 0.000 0.000 0.000 0.000 {method 'format' of 'str' objects} 2 0.000 0.000 0.000 0.000 decorator.py:4(track) 3 0.000 0.000 0.000 0.000 functools.py:43(update_wrapper) 1 0.000 0.000 0.000 0.000 functools.py:422(decorating_function) 21 0.000 0.000 0.000 0.000 {built-in method builtins.getattr} 15 0.000 0.000 0.000 0.000 {built-in method builtins.setattr} 2 0.000 0.000 0.000 0.000 functools.py:73(wraps) 3 0.000 0.000 0.000 0.000 {method 'update' of 'dict' objects} 1 0.000 0.000 0.000 0.000 functools.py:391(lru_cache) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} # 追踪结果 fib --> (0) --> 0 fib --> (1) --> 1 fib --> (2) --> 1 fib --> (1) --> 1 fib --> (0) --> 0 fib --> (1) --> 1 fib --> (2) --> 1 fib --> (3) --> 2 fib --> (4) --> 3 fib --> (1) --> 1 fib --> (0) --> 0 fib --> (1) --> 1 fib --> (2) --> 1 fib --> (3) --> 2 fib --> (0) --> 0 fib --> (1) --> 1 fib --> (2) --> 1 fib --> (1) --> 1 fib --> (0) --> 0 fib --> (1) --> 1 fib --> (2) --> 1 fib --> (3) --> 2 fib --> (4) --> 3 fib --> (5) --> 5 fib --> (6) --> 8 fib --> (1) --> 1 fib --> (0) --> 0 fib --> (1) --> 1 fib --> (2) --> 1 往后的省略...
使用装饰器的结果;
可以很明显的看到,使用缓存的时候,只调用了 11 次就得出了结果,并且花费时间只为 0.002 秒
fib_with_cache(10) 95 function calls (75 primitive calls) in 0.002 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.002 0.002 {built-in method builtins.exec} 1 0.000 0.000 0.002 0.002 decorator.py:1(<module>) 11/1 0.000 0.000 0.002 0.002 decorator.py:5(inner) 11/1 0.000 0.000 0.002 0.002 decorator.py:18(fib_with_cache) 11 0.002 0.000 0.002 0.000 {built-in method builtins.print} 2 0.000 0.000 0.000 0.000 decorator.py:4(track) 3 0.000 0.000 0.000 0.000 functools.py:43(update_wrapper) 11 0.000 0.000 0.000 0.000 {method 'format' of 'str' objects} 1 0.000 0.000 0.000 0.000 functools.py:422(decorating_function) 21 0.000 0.000 0.000 0.000 {built-in method builtins.getattr} 15 0.000 0.000 0.000 0.000 {built-in method builtins.setattr} 2 0.000 0.000 0.000 0.000 functools.py:73(wraps) 3 0.000 0.000 0.000 0.000 {method 'update' of 'dict' objects} 1 0.000 0.000 0.000 0.000 functools.py:391(lru_cache) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} # 追踪结果 fib_with_cache --> (0) --> 0 fib_with_cache --> (1) --> 1 fib_with_cache --> (2) --> 1 fib_with_cache --> (3) --> 2 fib_with_cache --> (4) --> 3 fib_with_cache --> (5) --> 5 fib_with_cache --> (6) --> 8 fib_with_cache --> (7) --> 13 fib_with_cache --> (8) --> 21 fib_with_cache --> (9) --> 34 fib_with_cache --> (10) --> 55
这个差距还不明显,我们再看下更多递归次数的情况:
调用了 4356617 次,花费 168.122 秒
fib(31) 17426519 function calls (8713287 primitive calls) in 168.122 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 168.122 168.122 {built-in method builtins.exec} 1 0.000 0.000 168.122 168.122 decorator.py:1(<module>) 4356617/1 8.046 0.000 168.122 168.122 decorator.py:5(inner) 4356617/1 4.250 0.000 168.122 168.122 decorator.py:12(fib) 4356617 150.176 0.000 150.176 0.000 {built-in method builtins.print} 4356617 5.650 0.000 5.650 0.000 {method 'format' of 'str' objects} 2 0.000 0.000 0.000 0.000 decorator.py:4(track) 3 0.000 0.000 0.000 0.000 functools.py:43(update_wrapper) 1 0.000 0.000 0.000 0.000 functools.py:422(decorating_function) 21 0.000 0.000 0.000 0.000 {built-in method builtins.getattr} 15 0.000 0.000 0.000 0.000 {built-in method builtins.setattr} 2 0.000 0.000 0.000 0.000 functools.py:73(wraps) 3 0.000 0.000 0.000 0.000 {method 'update' of 'dict' objects} 1 0.000 0.000 0.000 0.000 functools.py:391(lru_cache) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
fib_with_cache(31) 179 function calls (117 primitive calls) in 0.003 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.003 0.003 {built-in method builtins.exec} 1 0.000 0.000 0.003 0.003 decorator.py:1(<module>) 32/1 0.000 0.000 0.003 0.003 decorator.py:5(inner) 32/1 0.000 0.000 0.003 0.003 decorator.py:18(fib_with_cache) 32 0.002 0.000 0.002 0.000 {built-in method builtins.print} 32 0.000 0.000 0.000 0.000 {method 'format' of 'str' objects} 2 0.000 0.000 0.000 0.000 decorator.py:4(track) 3 0.000 0.000 0.000 0.000 functools.py:43(update_wrapper) 1 0.000 0.000 0.000 0.000 functools.py:422(decorating_function) 21 0.000 0.000 0.000 0.000 {built-in method builtins.getattr} 15 0.000 0.000 0.000 0.000 {built-in method builtins.setattr} 2 0.000 0.000 0.000 0.000 functools.py:73(wraps) 3 0.000 0.000 0.000 0.000 {method 'update' of 'dict' objects} 1 0.000 0.000 0.000 0.000 functools.py:391(lru_cache) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
而使用缓存装饰器的情况下只调用了32次,花费0.003秒
这个装饰器还提供 cache_clear() 用于清理缓存,以及 cache_info() 用于查看缓存信息,其他具体信息可以参考官网介绍:https://docs.python.org/3/library/functools.html
浙公网安备 33010602011771号