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装饰的函数接受的参数必须是不可变类型。
functools.lru_cache装饰器的更多相关文章
- python中functools.wraps装饰器的作用
functools.wraps装饰器用于显示被包裹的函数的名称 import functools def node(func): #@functools.wraps(func) def wrapped ...
- python functools.wraps装饰器模块
# -*-coding=utf-8 -*-#实现一个函数执行后计算执行时间的功能 __author__ = 'piay' import time, functools def foo(): ''' 定 ...
- Python 标准库中的装饰器
题目描述 1.简单举例 Python 标准库中的装饰器 2.说说你用过的 Python 标准库中的装饰器 1. 首先,我们比较熟悉,也是比较常用的 Python 标准库提供的装饰器有:property ...
- 用functools.lru_cache实现Python的Memoization
现在你已经看到了如何自己实现一个memoization函数,我会告诉你,你可以使用Python的functools.lru_cache装饰器来获得相同的结果,以增加方便性. 我最喜欢Python的原因 ...
- python 函数结果缓存一段时间的装饰器
把函数结果缓存一段时间,比如读取一个mongodb,mongodb中的内容又在发生变化,如果从部署后,自始至终只去读一次那就感触不到变化了,如果每次调用一个函数就去读取那太频繁了耽误响应时间也加大了c ...
- Python基础:13装饰器
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的应用有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同 ...
- Fluent_Python_Part3函数即对象,07-closure-decoration,闭包与装饰器
第7章 函数装饰器和闭包 装饰器用于在源码中"标记"函数,动态地增强函数的行为. 了解装饰器前提是理解闭包. 闭包除了在装饰器中有用以外,还是回调式编程和函数式编程风格的基础. 1 ...
- python 装饰器(三):装饰器实例(一)
示例 7-15 定义了一个装饰器,它会在每次调用被装饰的函数时计时,然后把经过的时间.传入的参数和调用的结果打印出来.示例 7-15 一个简单的装饰器,输出函数的运行时间 import time de ...
- python函数与方法装饰器
之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢. def fib_direct(n): assert n > 0, 'invalid n' if n < 3 ...
随机推荐
- VMware安装Centos7超详细过程
本篇文章主要介绍了VMware安装Centos7超详细过程(图文),具有一定的参考价值,感兴趣的小伙伴们可以参考一下 一.软硬件准备 软件:推荐使用VMwear,我用的是VMwear 12 镜像:Ce ...
- [C++]Yellow Cards - GYM - 102348A(Practice *) - CodeForces
1 Problem Description Problem The final match of the Berland Football Cup has been held recently. Th ...
- [转]将西部数据 My Passport Wireless 移动存储连接到任何支持的云存储上
原文标题:对西部数据 My Passport Wireless 移动存储进行 Linux 魔改 原文链接:https://linux.cn/article-8246-1.html 虽然 WD My P ...
- 82. 删除排序链表中的重复元素 II
# 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字,比如: # 输入: 1->2->3->3->4->4->5 # 输出: 1 ...
- Github上的python开源项目
Python开源项目,期待大家和我们一起共同维护 github排名榜单 https://github.com/trending github搜索榜单:https://github.com/search ...
- 在MFC中添加OpenGL窗口
虽然MFC已经落伍好多年,而且用来做界面非常的不好用...但是我既不会C#也不会QT,又需要使用OpenGL,就只能将就用了... 一.首先介绍Windows图像程序设计中几个重要的概念: G ...
- 详解Linux开源安全审计和渗透测试工具Lynis
转载自FreeBuf.COM Lynis是一款Unix系统的安全审计以及加固工具,能够进行深层次的安全扫描,其目的是检测潜在的时间并对未来的系统加固提供建议.这款软件会扫描一般系统信息,脆弱软件包以及 ...
- mysql中单个字段包含','转换成多条记录
问题:把value中的值取出作为另外一个表的where条件时,必须把value中的用','分隔的每一个id截取出来 解决方法: ),) ) #本文参考自网络某文章,非原创
- 《剑指offer》递推与循环,栈和队列,回溯 (牛客10.27)
难度 题目 知识点 07. 斐波那契数列 递推递归 - 两变量写法- 08. 跳台阶 同上 09. 变态跳台阶 dp 10. 矩形覆盖 同上 05. 用两个栈实现队列 模拟 ☆ 20. 包含min函数 ...
- 学习pandas apply方法,看这一篇就够了,你该这么学,No.10
最近好忙啊,好忙啊,忙的写不动博客了 时间过得飞快 一晃,一周就过去了 本着不进步就倒退的性格 我成功的在技术上面划水了一周 今天要学习的还是groupby的高级进阶 说是高级,其实就是比初级复杂了一 ...