
正文
python函数缓存 python 缓存
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
Python性能提升神器!lru_cache的介绍和讲解
我们经常谈论的缓存一词,更多的类似于将硬盘中的数据存放到内存中以至于提高读取速度,比如常说的redis,就经常用来做数据的缓存。 Python的缓存(lru_cache)是一种装饰在被执行的函数上,将其执行的结果缓存起来,当下次请求的时候,如果请求该函数的传参未变则直接返回缓存起来的结果而不再执行函数的一种缓存装饰器。
那它和redis的区别在哪?有什么优势?怎么使用? 下面为你讲解
1.现在我们先不使用缓存来写一个求两数之和的函数,并调用执行它两次:
执行结果
可以看到 test 被执行了两次,现在我们加上缓存再进行执行:
执行结果
可以看到 test 函数只被执行了一次,第二次的调用直接输出了结果,使用了缓存起来的值。
2.当我们使用递归求斐波拉契数列 (斐波那契数列指的是这样一个数列:0,1,1,2,3,5,8,它从第3项开始,每一项都等于前两项之和) 的时候,缓存对性能的提升就尤其明显了:
不使用缓存求第40项的斐波拉契数列
执行时间
使用缓存求第40项的斐波拉契数列:
执行时间
两个差距是非常明显的,因为不使用缓存时,相当于要重复执行了很多的函数,而使用了 lru_cache 则把之前执行的函数结果已经缓存了起来,就不需要再次执行了。
查看lru_cache源码会发现它可以传递两个参数: maxsize 、 typed :
代表被lru_cache装饰的方法最大可缓存的结果数量 (被装饰方法传参不同一样,则结果不一样;如果传参一样则为同一个结果) , 如果不指定传参则默认值为128,表示最多缓存128个返回结果,当达到了128个时,有新的结果要保存时,则会删除最旧的那个结果。如果maxsize传入为None则表示可以缓存无限个结果;
默认为false,代表不区分数据类型,如果设置为True,则会区分传参类型进行缓存,官方是这样描述的:
但在python3.9.8版本下进行测试,typed为false时,按照官方的测试方法测试得到的还是会被当成不同的结果处理,这个时候typed为false还是为true都会区别缓存,这与官方文档的描述存在差异:
执行结果
但如果是多参数的情况下,则会被当成一个结果:
执行结果
这个时候设置typed为true时,则会区别缓存:
执行结果
当传参个数大于1时,才符合官方的说法,不清楚是不是官方举例有误
当传递的参数是dict、list等的可变参数时,lru_cache是不支持的,会报错:
报错结果
缓存 缓存位置 是否支持可变参数 是否支持分布式 是否支持过期时间设置 支持的数据结构 需单独安装 redis 缓存在redis管理的内存中 是 是 是 支持5种数据结构 是 lru_cache 缓存在应用进程的内存中,应用被关闭则被清空 否 否 否 字典(参数为:key,结果为:value) 否
经过上面的分析,lru_cache 功能相对于redis来说要简单许多,但使用起来更加方便,适用于小型的单体应用。如果涉及的缓存的数据种类比较多并且想更好的管理缓存、或者需要缓存数据有过期时间(类似登录验证的token)等,使用redis是优于lru_cache的。
相关问答
Q1: python3_原生 LRU 缓存
原生 LRU 缓存(最低 Python 版本为 3.2)
目前python函数缓存,几乎所有层面上python函数缓存的软件和硬件中都需要缓存。Python 3 将 LRU(最近最少使用算法)缓存作为一个名为「lru_cache」的装饰器python函数缓存,使得对缓存的使用非常简单。
下面是一个简单的斐波那契函数,python函数缓存我们知道使用缓存将有助于该函数的计算,因为它会通过递归多次执行相同的工作。
现在,我们可以使用「lru_cache」来优化它(这种优化技术被称为「memoization」)。通过这种优化,我们将执行时间从几十秒降低到python函数缓存了几秒。
Q2: python 缓存
详解:
一.
1.int 类型的缓存
[-5, 256]的整型,只要Python解释器一运行,这些数值就加载到python函数缓存了内存
2.free_list:float、list、touple、dict等都是这种方式
当一个对象引用计数为0时,按理说就应该被垃圾回收python函数缓存了,但是Python不是这么做的,而是将对象放入到free_list链表里面。这样,以后再去创建该对象时,不会重新开辟内存,而是直接使用free_list里面的
Q3: Python性能优化:增大正则表达式编译缓存
关键词:正则表达式 | 缓存 | 性能优化
Python 3 python函数缓存的 re 库中python函数缓存,对正则表达式的编译函数 re.compile() 调用python函数缓存了私有函数 re._compile() ,但更根本上编译的计算是由 sre_compile.compile() 完成的,而 re._compile() 中对编译好的表达式进行了缓存,使用 _MAXCACHE 将缓存大小硬编码为512。以下是 re._compile() 的源码,摘自: (3.6,3.7里也没有变化)
在某些 大规模应用场景 下,512的缓存显然太小了一些,为了摆脱这个瓶颈但不去碰cpython的源码,python函数缓存我们可以自己改写 re._compile() ,从而实现自定义缓存大小( max_regex_cache ),轻松排个10000出来。原函数里很多语句都不知道干嘛用的,但照葫芦画瓢总没错。
调用方法:
进一步优化是将这个类变成Singleton(之后python函数缓存我应该会专门写一篇),以及 多模块共享 。
Q4: python缓存数据除了全局变量
python缓存数据除了全局变量,就是Python将一些值预先存好,当定义一个变量,并给他赋值时,会先匹配这些缓存好的值,如果有匹配的话,就将变量指向对应的内存。
关于python函数缓存和python 缓存的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。







