缓存概念

缓存是一种将定量数据加以保存以备迎合后续请求的处理方式,目的是为了加快数据的检索速度
下面看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# -*- coding: utf-8 -*-
import datetime
import random
class MyCache:
""""""
def __init__(self):
"""Constructor"""
self.cache = {}
self.max_cache_size = 10
def __contains__(self, key):
"""
根据该键是否存在于缓存当中返回True或者False
"""
return key in self.cache
def update(self, key, value):
"""
更新该缓存字典,您可选择性删除最早条目
"""
if key not in self.cache and len(self.cache) >= self.max_cache_size:
self.remove_oldest()
self.cache[key] = {'date_accessed': datetime.datetime.now(),
'value': value}
def remove_oldest(self):
"""
删除具备最早访问日期的输入数据
"""
oldest_entry = None
for key in self.cache:
if oldest_entry == None:
oldest_entry = key
elif self.cache[key]['date_accessed'] < self.cache[oldest_entry]['date_accessed']:
oldest_entry = key
self.cache.pop(oldest_entry)
@property
def size(self):
"""
返回缓存容量大小
"""
return len(self.cache)
if __name__ == '__main__':
#测试缓存
keys = ['test', 'red', 'fox', 'fence', 'junk', \
'other', 'alpha', 'bravo', 'cal', 'devo', 'ele']
s = 'abcdefghijklmnop'
cache = MyCache()
for i, key in enumerate(keys):
if key in cache:
continue
else:
value = ''.join([random.choice(s) for i in range(20)])
cache.update(key, value)
print("#%s iterations, #%s cached entries" % (i+1, cache.size))

在 Python 的 3.2 版本中,引入了一个非常优雅的缓存机器,即 functool 模块中的 lru_cache 装饰器。如果要在 python2 中使用 lru_cahce 需要安装 functools32。lru_cache 原型如下:@functools.lru_cache(maxsize=None, typed=False)
使用functools模块的lur_cache装饰器,可以缓存最多 maxsize 个此函数的调用结果,从而提高程序执行的效率,特别适合于耗时的函数。参数maxsize为最多缓存的次数,如果为None,则无限制,设置为2n时,性能最佳;
lru_cache 装饰的函数会有 cache_clearcache_info 两个方法,分别用于清除缓存和查看缓存信息。
这里用一个简单的示例演示 lru_cache 效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from functools import lru_cache
@lru_cache(None)
def add(x, y):
print("calculating: %s + %s" % (x, y))
return x + y
print(add(1, 2))
print(add(1, 2))
print(add(2, 3))
#输出结果:
calculating: 1 + 2
3
3
calculating: 2 + 3
5

从结果可以看出,当第二次调用 add(1, 2) 时,并没有真正执行函数体,而是直接返回缓存的结果。

参考