57个挑战之50v3-高阶-使用内存来加速访问

接昨天的第二个挑战问题:


找到方法来把电影信息做缓存,这样不需要不断地访问外部的API。

缓存原理比较简单,好比去下电影,每次看电影都要到电影网站上实时看,这样速度很慢,因为网络慢,最好的方式是存在本地。

缓存的好处是 速度快、成本低, 缺点是可能会有延迟。因此出现了一堆算法,保障数据和实际的数据(比如“网站上存储的用户的cookie id”)是内容一致的。

这篇掘金的文章翻译的还可以,

https://juejin.cn/post/7000696203545411615


但找了一圈,还是发现英文原版的实现方法,讲的比较清晰:

https://towardsdatascience.com/how-to-speed-up-your-python-code-with-caching-c1ea979d0276

里面讲了两个方法,一个是自己写脚本的,一个是直接引入一个python的cache 工具包,cachetools. 发现还有一个链接,直接解释如何用cache来计算斐波那契函数的,学过一些算法的同学就知道,递归函数中,如果用cache,可以大大提高访问的效率,o(N) 这个还是牛逼的。

自己写脚本:


而用cachetools 就很简单了,直接引用一下即可。


看上面图,只用两行,是不是很简单啊。

其中:cache = TTLCache(maxsize=100, ttl=86400)

指的是可以缓存100个对象,缓存存活时间是86400s

另外,这里用time.time() 函数来进行计算,判断缓存的效果。

好,上代码

"""
Here is your key: 32e196ec

Please append it to all of your API requests,

OMDb API: http://www.omdbapi.com/?i=tt3896198&apikey=32e196ec

Click the following URL to activate your key: http://www.omdbapi.com/apikey.aspx?VERIFYKEY=f6ef723e-500f-481e-a347-86af2aa126bc
If you did not make this request, please disregard this email.

"""
import io
import time
import requests,json
import tkinter as tk
from PIL import Image,ImageTk
from cachetools import cached,TTLCache

cache = TTLCache(maxsize=100,ttl=86400)
apikey = "32e196ec"

@cached(cache)
def get_input():
    title = input("Enter the name of a movie:").replace(" ","+")
    start_time = time.time()
    url = "http://www.omdbapi.com/?&t={0}&plot=full&apikey={1}".format(title,apikey)
    r = requests.get(url)
    end_time = time.time()
    print("耗时: {0}".format(end_time - start_time))
    return r


def get_movie(r):
    data = json.loads(r.content)
    print("Title: {0}".format(data))
    print(data)
    return data

def display_movie(data):
    print("Title: {0}".format(data['Title']))
    print("Year: {0}".format(data['Year']))
    print("Rating: {0}".format(data['Rated']))
    print("Running Time: {0}".format(data['Runtime']))
    print("\n Description: {0}".format(data['Plot']))


def display_movie_pic(data):
    window = tk.Tk()
    canvas = tk.Canvas(window,bg='white',height=768,width=1024)
    url=data["Poster"]
    print(url)
    image_bytes = requests.get(url).content
    data_stream = io.BytesIO(image_bytes)
    pil_image = Image.open(data_stream)
    photo=ImageTk.PhotoImage(pil_image)
    #w,h = pil_image.size
    #print(w)
    label1 = tk.Label(window,text="Rating: {0}".format(data['Rated']),image=photo,compound="center",font=("微软雅黑",20),fg='white')
    #image1 = canvas.create_image(260,100,anchor='nw',image=photo)
    label1.pack()
    window.mainloop()



if __name__ == '__main__':
    r = get_input()
    data = get_movie(r)
    display_movie(data)
    display_movie_pic(data)

运行时间比较:


可以看到两次运行,第一次没有命中,需要读取,第二次命中后,时间直接是第一次的1/10

这篇感觉讲了斐波那契,讲了递归,讲了使用缓存,相对来说比较高阶一点。

其实看着高阶一点的东西,只是多了一些算法而已,没那么恐怖。

斐波那契+缓存来加速递归的效率,记得是哪个大学算法的一个课程。有心的同学可以关注下,o(n), o(n平方),o(1) ,数据量及一旦变大,算法的作用就明显了。

原文链接:,转发请注明来源!