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 ...
随机推荐
- expect实现免交互
如果想写一个能够自动处理输入输出的脚本又不想面对C或Perl,那么expect是最好的选择.它可以用来做一些Linux下无法做到交互的一些命令操作. (1).安装和使用expect expect是不会 ...
- Spring Boot连接MySQL报错“Internal Server Error”的解决办法
报错信息如下: {timestamp: "2018-06-14T03:48:23.436+0000", status: 500, error: "Internal Ser ...
- python中Requests的重试机制
requests原生支持 import requests from requests.adapters import HTTPAdapter s = requests.Session() # 重试次数 ...
- ORA-00054:Orcacle表锁定
查询被锁的session_id select session_id from v$locked_object; 查询结果----------------------SESSION_ID8 查询被锁se ...
- C语言笔试
1.一个C程序的执行时从本程序的main开始,到main结束. 2.C语言规定else总是与在其之前的未配对的最近if配对. 3.int型数据在内存中的存储形式是补码. 4.数组一旦定义其大小是固定的 ...
- 如何制作红蓝3d电影(详细教程)
自20世纪初以来,电影制作人一直试图通过制作3D电影来利用我们的双眼.现在,由于大量相对实惠的3D电视,你可以享受电影院以外的额外空间 - 你自己拍摄的视频.对于大预算的电影,电影摄影师使用两个相连的 ...
- kubernetes版本apiversion简单说明
在使用yaml文件部署Deployment项目时,出现过 error: error validating "xx-Deployment.yaml": error validatin ...
- Docker跨主机网络实践
Docker使用中网络管理是最麻烦的,在项目初始化前期就需要进行合理的规划,如果在比较理想的单主机的网络通信是比较简单的,但如果涉及到跨主机的网络就需要使用docker自带的overlay netwo ...
- linux基础命令笔记
配置IP地址 vi /etc/sysconfig/network-scripts/ifcfg-eth0 忘记root密码grub e 选择kernel按e 输入single b 1:目录及文件的基本操 ...
- 使用Dreamweaver制作简单网站(二)
继续上周没完成的 一.新建iframe.css 1.点击文件-选择新建-css 2.ctrl+s保存为iframe.css 在style文件夹下. 3.回到main.html 右键选择-附加样式表,选 ...