Python性能提升神器!lrucache的介绍和讲解
一、前言
我们经常谈论的缓存一词,更多的类似于将硬盘中的数据存放到内存中以至于提高读取速度,比如常说的redis,就经常用来做数据的缓存。 Python的缓存(lru_cache)是一种装饰在被执行的函数上,将其执行的结果缓存起来,当下次请求的时候,如果请求该函数的传参未变则直接返回缓存起来的结果而不再执行函数的一种缓存装饰器。
那它和redis的区别在哪?有什么优势?怎么使用? 下面为你讲解 二、举例说明
1.现在我们先不使用缓存来写一个求两数之和的函数,并调用执行它两次: def test(a, b): print("开始计算a+b的值...") return a + b print("1+2等于:", test(1, 2)) print("1+2等于:", test(1, 2))
执行结果 开始计算a+b的值... 1+2等于: 3 开始计算a+b的值... 1+2等于: 3
可以看到 test 被执行了两次,现在我们加上缓存再进行执行:from functools import lru_cache @lru_cache def test(a, b): print("开始计算a+b的值...") return a + b print(test(1, 2)) print(test(1, 2))
执行结果 开始计算a+b的值... 1+2等于: 3 1+2等于: 3
可以看到 test 函数只被执行了一次,第二次的调用直接输出了结果,使用了缓存起来的值。
2.当我们使用递归求斐波拉契数列 (斐波那契数列指的是这样一个数列:0,1,1,2,3,5,8,它从第3项开始,每一项都等于前两项之和) 的时候,缓存对性能的提升就尤其明显了:
不使用缓存求第40项的斐波拉契数列 import datetime def fibonacci(num): # 不使用缓存时,会重复执行函数 return num if num < 2 else fibonacci(num - 1) + fibonacci(num - 2) start = datetime.datetime.now() print(fibonacci(40)) end = datetime.datetime.now() print("执行时间", end - start)
执行时间 执行时间 0:00:29.004424
使用缓存求第40项的斐波拉契数列: @lru_cache def fibonacci(num): # 不使用缓存时,会重复执行函数 return num if num < 2 else fibonacci(num - 1) + fibonacci(num - 2)
执行时间 执行时间 0:00:00
两个差距是非常明显的,因为不使用缓存时,相当于要重复执行了很多的函数,而使用了 lru_cache 则把之前执行的函数结果已经缓存了起来,就不需要再次执行了。三、lru_cache 用法1.参数详解
查看lru_cache源码会发现它可以传递两个参数: maxsize 、typed :def lru_cache(maxsize=128, typed=False): """Least-recently-used cache decorator. If *maxsize* is set to None, the LRU features are disabled and the cache can grow without bound. ... """ 1) maxsize
代表被lru_cache装饰的方法最大可缓存的结果数量 (被装饰方法传参不同一样,则结果不一样;如果传参一样则为同一个结果) , 如果不指定传参则默认值为128,表示最多缓存128个返回结果,当达到了128个时,有新的结果要保存时,则会删除最旧的那个结果。如果maxsize传入为None则表示可以缓存无限个结果; 2)typed
默认为false,代表不区分数据类型,如果设置为True,则会区分传参类型进行缓存,官方是这样描述的:
如果 typed 为True,则将分别缓存不同类型的参数, 例如,f(3.0)和f(3)将被视为具有明显的结果。
但在python3.9.8版本下进行测试,typed为false时,按照官方的测试方法测试得到的还是会被当成不同的结果处理,这个时候typed为false还是为true都会区别缓存,这与官方文档的描述存在差异: from functools import lru_cache @lru_cache def test(a): print("函数被调用了...") return a print(test(1.0)) print(test(1))
执行结果 函数被调用了... 1.0 函数被调用了... 1
但如果是多参数的情况下,则会被当成一个结果: from functools import lru_cache @lru_cache def test(a, b): print("函数被调用了...") return a , b print(test(1.0, 2.0)) print(test(1, 2))
执行结果 函数被调用了... (1.0, 2.0) (1.0, 2.0)
这个时候设置typed为true时,则会区别缓存: from functools import lru_cache @lru_cache(typed=True) def test(a, b): print("函数被调用了...") return a , b print(test(1.0, 2.0)) print(test(1, 2))
执行结果 函数被调用了... (1.0, 2.0) 函数被调用了... (1, 2)
当传参个数大于1时,才符合官方的说法,不清楚是不是官方举例有误 2. lru_cache不支持可变参数
当传递的参数是dict、list等的可变参数时,lru_cache是不支持的,会报错: from functools import lru_cache @lru_cache def test(a): print("函数被执行了...") return a print(test({"a":1}))
报错结果 TypeError: unhashable type: "dict" 四、lru_cache 与redis的区别
缓存 缓存位置 是否支持可变参数 是否支持分布式 是否支持过期时间设置 支持的数据结构 需单独安装 redis 缓存在redis管理的内存中 是 是 是 支持5种数据结构 是 lru_cache 缓存在应用进程的内存中,应用被关闭则被清空 否 否 否 字典(参数为:key,结果为:value) 否 五、总结
经过上面的分析,lru_cache 功能相对于redis来说要简单许多,但使用起来更加方便,适用于小型的单体应用。如果涉及的缓存的数据种类比较多并且想更好的管理缓存、或者需要缓存数据有过期时间(类似登录验证的token)等,使用redis是优于lru_cache的。
iOS14代码曝光新系统功能苹果的保密工作做得是一年不如一年,你看,近期又有外媒在iOS14代码中发现了新的功能亮点。壁纸功能更新其实苹果每一代新系统都会更新壁纸,iOS13中壁纸可以选择为动态静态和实时三个
青春四件套荣耀畅玩6A名字的由来你可知道?5月23日荣耀总裁赵明携手青春四件套站台荣耀新品发布会,其中青春四件套中,最显眼的当属荣耀畅玩6A了,可你知道荣耀畅玩6A名字的由来么?在发布会上荣耀总裁赵明,介绍荣耀畅玩6A,这
爷们VS娘们苹果MacBookAirM1对比ThinkPadX1Nano0X00题外话2013年初入职场,我正在为选什么笔记本发愁的时候,看到了一篇爷们VS娘们!X1Carbon对比苹果Air评测,来自PCOnline编辑WangJun老师的文章。如果
手办开箱滋滋滋!北半球最帅的男人,闪电法师登场SuperCell皇室战争的周边产品非常丰富,叔之前买过一对飞龙宝宝闪电飞龙手机支架。大型的手办已经出过多款,从最早的野猪骑士(野猪)到超级骑士(超骑),再到闪电法师。已经是第三款
建邦基金与两县政府合作组建防贫基金和乡村振兴基金2020年5月,大名县扶贫办正式聘用建邦基金为防贫产业基金的基金管理人,建邦基金开创了全省首例与政府扶贫办共同出资成立的防贫产业及乡村振兴基金。该基金主要投资于邯郸市大名县可带动农
河北汽车产业链这样布局1,节能汽车产业链。高效发动机及(插电)混动电动增程乘用车用发动机汽油机增压器电涡流缓速器等涡轮增压器高效自动变速箱及高压混动变速箱系统电驱动两档电控减速器自动变速器电磁阀等关键零
河北投资405亿元,谋划85个重点项目,搭建氢能全产业链河北省发改委日前,河北省发展改革委印发河北省2021年氢能产业重点谋划推进项目清单(第二批),确定85个氢能产业重点谋划推进项目,其中,制氢项目29个,氢能装备项目8个,加氢站项目
硬核升级VOOC4。0骁龙730G处理器OPPOK5热销不断随着智能手机的发展,手机的性能也越来越强大,千元机亦是如此。但手机拥有高性能的同时,功耗和续航等问题的需求势必水涨船高。为了解决这一痛点,各大厂商在电池容量快充方案上大展身手。提及
文飞我将伸手摘月,若是失败,仍与星辰同在生命之所以有趣,在于我们有机会把挑战经营成习惯,把自己经营成对手,把工作经营成事业,把梦想经营成行动。3月4日,长城汽车官宣升任文飞为沙龙智行CEO。当晚,文飞一篇小文凡心所向,素
高合一路向暖静候5月花开高合HiPhiX将于5月正式批量交付。近日,高合汽车发布消息称,位于江苏盐城的高合工厂正稳步推进量产,将按既定计划保质保量交付用户。与此同时,首批10家高合中心已在北上广深杭蓉汉等
即使身处千里之外,也可与家庭设备互动每次有快递送到家里,家里却没人开门?刚下班想要提前打开家里的空调?想要扫地机每天定时清扫?其实,现在已经有许多设备可以让我们解决这些问题。比如米家万能遥控器Broadlink万能遥