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 ...
随机推荐
- 【S/4系列专栏】关于S/4你想知道的问题与答案
转自:http://www.sohu.com/a/152235225_652820 S/4系列专栏将收集国内的实施案例,从各个角度进行分析,包括S/4的由来,S/4各个版本的变化,企业是否有必要选择S ...
- SpringBoot: 12.异常处理方式2(使用@ExceptionHandle注解)(转)
1.编写controller package com.bjsxt.controller; import org.springframework.stereotype.Controller; impor ...
- 从MOV PC,PC;(或者ADDPC,PC,#4 )看ARM的三级流水线过程
3级流水线如上图所示(PC为程序计数器),流水线使用3个阶段,因此指令分3个阶段执行. ⑴ 取指从存储器装载一条指令 ⑵ 译码识别将要被执行的指令 ⑶ 执行处理指令并将结果写会寄存器 以前学过的51单 ...
- 二分类Logistic回归模型
Logistic回归属于概率型的非线性回归,分为二分类和多分类的回归模型.这里只讲二分类. 对于二分类的Logistic回归,因变量y只有“是.否”两个取值,记为1和0.这种值为0/1的二值品质型变量 ...
- Django:(07)数据库
一.ORM框架 ORM ,Object relational mapping 对象关系映射. 把类和数据库表对应,把对象和表记录对应,通过类和对象操作数据库表中的数据,而不需要编写SQL语句. Dja ...
- OpenGL(5)——变换
学习三种变换:Scaling, Rotation和Translation. 上学期修了Kobbelt教授(男神!)的图形学基础课,这部分内容已经接触过. 添加GLM库,直接给出齐次坐标系下的变换矩阵和 ...
- ASP.NET 拼多多用户登录授权后使用code去换取access_token
一.拼多多开放平台 由于本人刚毕业进公司实习 遇到一些问题然后想通过博客来记录和分享给大家一起学习. 第一次写博客没什么经验不是写的很好 请大家多多关照 嘴下留情哈哈 谢谢! 好了 话不多说直接进入主 ...
- 连接池和JDBCTemplate
一:什么是连接池?使用连接池的好处是什么? 连接池就是一个存放数据库连接对象的容器.当系统初始化后,就会向数据库申请一些连接对象存放到容器里,用的时候直接从容器里取,用完后放回连接池. 连接池可以提高 ...
- Java入门请不要放弃,学习路线以及侧重点分析
前言: ●众多的语言,到底哪一门才是适合我的? ●我们为什么要学习Java语言呢? ●Java学习路线 我们可以通过今年最新的TIOBE编程语言排行榜看到,JAVA在"昨天".和& ...
- sysbench的简单安装
1. 下载 可以到网站上面找 我用到的这个是201908最新的 wget https://src.fedoraproject.org/repo/pkgs/sysbench/sysbench-1.0.1 ...