能看到这篇文章的同学,应该都对缓存这个概念不陌生,CPU中也有一级缓存、二级缓存和三级缓存的概念。缓存可以解决哪些问题?我们直接把网上的一段话放上来:
所以这一节,我们就来讲一下Python中的缓存,怎么使用Python中的缓存功能,可以为程序提供多高的加速?本节课涉及的内容比较多,下面三个文章是基础:
如何写出高性能的Python之修饰符functools.wraps
Python的标准库中,包含了模块functools,这个模块主要用于高阶函数。lru_cache()是functools中的一个函数,它可以通过应用缓存来降低函数的执行时间。
lru_cache()
的语法如下:
@lru_cache(maxsize=128, typed=False)
其中,maxsize
表示缓存大小,也就是指定保留的元素个数;如果希望缓存区大小不受限制,可将这个参数设置为None。typed
如果被设置为True,则不同类型的参数会被独立缓存,比如f(3)和f(3.0)就会被存储在两个独立的缓存中。
缓存应用最直观的地方就是计算斐波那契数列,斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为兔子数列,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
斐波那切数列的Python代码也比较简单:
def fibonacci(n):
if n<1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
在ipython中,我们看一下计算fibonacci(20)
所需要的时间:
%timeit fibonacci(20)
4.5 ms ± 166 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
需要4.5ms左右的时间才能计算完成,时间确实是比较长的了。但从代码中也可以看出来,由于没有重用之前计算的斐波那契数列,导致这种算法的时间复杂度大约为O(2^N).
在函数前使用修饰符lru_cache
:
@lru_cache(maxsize=128)
def fibonacci_cache(n):
if n<1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
此时再看运行时间:
%timeit fibonacci_cache(20)
99 ns ± 7 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
可以看到,时间缩短了45000倍,这个效率的提高是惊人的,也是非常可观的。
完