缓存性能调优方面
- 缓存淘汰策略:
- LRU(最近最少使用):使用
collections.OrderedDict
实现LRU缓存淘汰策略。当缓存满时,删除最久未使用的项。示例代码如下:
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
self.capacity = capacity
self.cache = OrderedDict()
def get(self, key):
if key not in self.cache:
return -1
value = self.cache.pop(key)
self.cache[key] = value
return value
def put(self, key, value):
if key in self.cache:
self.cache.pop(key)
elif len(self.cache) == self.capacity:
self.cache.popitem(last=False)
self.cache[key] = value
- LFU(最不经常使用):可以使用字典嵌套实现,一个字典记录每个键的访问频率,另一个字典记录键值对。每次访问时更新频率,淘汰时选择频率最低的键。
- 数据结构优化:
- 减少内存占用:如果缓存的数据是一些简单类型,如整数、字符串等,可以考虑使用
array
模块代替普通列表来存储大量此类数据,以减少内存占用。例如,如果缓存的值都是整数:
import array
cache_values = array.array('i') # 'i'表示有符号整数
- 提高查找效率:Python字典本身查找效率已经很高(平均时间复杂度为O(1)),但如果数据量非常大,可以考虑使用
bitarray
库来存储布尔类型的缓存数据,其查找和设置操作效率高且节省内存。
- 锁机制优化:
- 在高并发场景下,使用
threading.Lock
或multiprocessing.Lock
对缓存操作进行加锁,防止多个线程或进程同时修改缓存导致数据不一致。例如:
import threading
class SafeCache:
def __init__(self):
self.cache = {}
self.lock = threading.Lock()
def get(self, key):
with self.lock:
return self.cache.get(key)
def set(self, key, value):
with self.lock:
self.cache[key] = value
- 对于读多写少的场景,可以使用
threading.RLock
(可重入锁)或multiprocessing.RLock
,并结合读写锁(threading.Condition
实现读写锁)来提高性能,允许多个读操作同时进行,写操作则独占锁。
结合设计模式管理和使用缓存
- 单例模式:
- 确保缓存对象全局唯一,避免重复创建缓存实例浪费资源。示例代码如下:
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Cache(metaclass=SingletonMeta):
def __init__(self):
self.cache = {}
def get(self, key):
return self.cache.get(key)
def set(self, key, value):
self.cache[key] = value
- 代理模式:
- 缓存代理:可以创建一个代理类,在对缓存进行操作前,先检查是否满足某些条件(如缓存是否可用,是否需要更新等)。示例代码如下:
class Cache:
def __init__(self):
self.cache = {}
def get(self, key):
return self.cache.get(key)
def set(self, key, value):
self.cache[key] = value
class CacheProxy:
def __init__(self, cache):
self.cache = cache
def get(self, key):
# 可以在这里添加额外逻辑,如检查缓存是否过期
return self.cache.get(key)
def set(self, key, value):
# 可以在这里添加额外逻辑,如记录缓存操作日志
self.cache.set(key, value)