Python缓存神器cachetools:提高程序性能的利器,一文详解其缓存算法

简介: Python缓存神器cachetools:提高程序性能的利器,一文详解其缓存算法

前言


春山如黄,琬琰满枝,

烨烨清风,漫舞天地。


一、cachetools库简介以及详细使用


1-1、定义


cachetools : 是一个Python第三方库,提供了多种缓存算法的实现。缓存是一种用于临时存储计算结果的技术,以避免在后续计算中重复执行相同的计算。使用缓存可以提高应用程序的性能和响应速度。


1-2、多种缓存策略


cachetools 提供了以下常见的缓存策略

  • Least Recently Used (LRU): 这种策略会移除最近最少使用的条目。当需要为新的条目腾出空间时,最近最少使用的条目将被移除。这是一种常见的缓存策略,适用于大多数场景。
  • Most Recently Used (MRU): 这种策略会移除最近最常使用的条目。当需要为新的条目腾出空间时,最近最常使用的条目将被移除。这种策略适用于一些特殊场景,例如当最近访问的数据不太可能再次访问时。
  • Random Replacement (RR): 这种策略会随机移除一个条目。当需要为新的条目腾出空间时,随机选择一个条目进行移除。这种策略实现简单,但性能相对较差。
  • First-In-First-Out (FIFO): 这种策略会按照条目添加到缓存的顺序进行移除。先添加的条目先被移除。这种策略适用于一些特定场景,例如缓存的数据具有固定生命周期。


import cachetools
# 创建 LRU 缓存
lru_cache = cachetools.LRUCache(maxsize=100)
# 创建 MRU 缓存
mru_cache = cachetools.MostRecentlyUsed(maxsize=100)
# 创建 RR 缓存
rr_cache = cachetools.Random(maxsize=100)
# 创建 FIFO 缓存
fifo_cache = cachetools.FIFO(maxsize=100)


注意:

maxsize参数代表的是缓存中可以存储的最大条目数量,而不是字符数。在这个例子中,maxsize=10000表示缓存中最多可以存储10000个不同的键值对。

关于maxsize的最大值,理论上它取决于你的系统内存和应用程序的需求。实际使用中,你需要根据你的应用程序的内存使用情况和性能需求来决定一个合适的maxsize。通常,设置一个较大的maxsize可以提高缓存命中率,从而提高程序性能,但同时也会增加内存消耗。因此,在设置maxsize时,需要权衡程序性能和内存使用之间的关系。

maxsize参数最好设置为2的幂次方,这样可以在内部哈希表扩展时更加高效。例如,可以设置为1024、2048、4096等。


1-3、缓存操作:缓存对象支持类似字典的操作

例如:添加、获取、删除和更新缓存项

# 类似于字典操作
# 添加缓存项
lru_cache["key"] = "value"
# 获取缓存项
value = lru_cache.get("key", "default_value")
# 删除缓存项
if "key" in lru_cache:
    del lru_cache["key"]
# 更新缓存项
lru_cache["key"] = "new_value"


1-4、设置数据生存时间(TTL)


cachetools : 还支持为缓存项设置生存时间(TTL)。当缓存项的生存时间到期后,该项将被自动移除。


import cachetools
import time
# 创建一个带 TTL 的缓存对象
ttl_cache = cachetools.TTLCache(maxsize=100, ttl=60)
# 添加缓存项
ttl_cache["key"] = "value"
# 等待一段时间,让缓存项过期
time.sleep(61)
# 此时缓存项已过期,尝试获取时将返回默认值
value = ttl_cache.get("key", "default_value")


1-5、自定义缓存策略


cachetools: 允许自定义缓存策略。要实现一个自定义的缓存策略,需要继承 cachetools.Cache 类,并实现相应的方法。例如,实现一个简单的大小有限制的缓存:

import cachetools
class SizeLimitedCache(cachetools.Cache):
    def __init__(self, maxsize):
        super().__init__(maxsize=maxsize)
    def __getitem__(self, key, cache_getitem=dict.__getitem__):
        return cache_getitem(self, key)
    def __setitem__(self, key, value, cache_setitem=dict.__setitem__):
        if len(self) >= self.maxsize:
            self.popitem(last=False)  # 删除第一个缓存项
        cache_setitem(self, key, value)
# 使用自定义缓存策略
custom_cache = SizeLimitedCache(maxsize=100)


1-6、缓存装饰器

cachetools: 还提供了一些缓存装饰器,可以方便地将缓存应用于函数或方法。

import cachetools
# 使用 LRU 缓存装饰函数
@cachetools.func.ttl_cache(maxsize=100, ttl=60)
def get_data_from_api(api_url, params):
    response = requests.get(api_url, params=params)
    response.raise_for_status()
    data = response.json()
    return data
# 使用缓存的函数
data = get_data_from_api("https://api.example.com/data", {"param1": "value1", "param2": "value2"})


1-7、缓存清理

cachetools: 提供了一些方法,可以手动清理缓存

import cachetools
# 创建 LRU 缓存
lru_cache = cachetools.LRUCache(maxsize=100)
# 手动清空缓存
lru_cache.clear()
# 移除所有过期缓存项
lru_cache.expire()
# 移除最近最少使用的缓存项
lru_cache.popitem(last=False)


二、cachetools 使用示例


在这个示例中,我们使用 cachetools.LRUCache 创建一个 LRU 缓存。当我们调用 get_data_from_api() 函数时,会先检查缓存中是否有数据。如果缓存中有数据,就直接返回缓存的数据,避免了重复请求接口,提高了程序性能。

import requests
import cachetools
# 创建一个 LRU 缓存,最大容量为 100
cache = cachetools.LRUCache(maxsize=100)
def get_data_from_api(url):
    if url in cache:
        return cache[url]  # 如果数据已经在缓存中,直接返回缓存的数据
    response = requests.get(url)
    response.raise_for_status()
    data = response.json()
    cache[url] = data  # 将数据存储在缓存中
    return data
# 使用缓存的函数
data = get_data_from_api("https://api.example.com/data")


三、错误汇总

3-1、TypeError: unhashable type: ‘dict’


错误来源:我想要直接将一个字典,作为cachetools缓存的键(key),这样是会报错的。


这个错误是因为字典(dict)类型在Python中是不可哈希(unhashable)的,因此不能直接将字典作为cachetools缓存的键(key)。要解决这个问题,可以将字典转换为一个可哈希的类型,比如字符串(str)或元组(tuple)。


以下是一个示例,将字典转换为字符串作为键:

import requests
import cachetools
import json
cache = cachetools.LRUCache(maxsize=100)
def get_data_from_api(api_url, params):
    # 将字典转换为字符串,并确保key的顺序一致,避免相同内容的字典生成不同的字符串
    cache_key = json.dumps(params, sort_keys=True)
    if cache_key in cache:
        return cache[cache_key]
    response = requests.get(api_url, params=params)
    response.raise_for_status()
    data = response.json()
    cache[cache_key] = data
    return data
# 使用缓存的函数
params = {"param1": "value1", "param2": "value2"}
data = get_data_from_api("https://api.example.com/data", params)


在这个示例中,我们将params字典转换为一个字符串,然后将字符串作为缓存的键。当调用接口获取数据时,Python会检查缓存中是否有数据。如果缓存中有数据,就直接返回缓存的数据,避免了重复请求接口,提高了程序性能。


总结


emmm,五一前忘记倒掉壶里的茶水了,都长毛了!!

相关文章
|
4天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
21 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
4天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
16 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
4天前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
16 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
8天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
25 2
|
10天前
|
机器学习/深度学习 算法 5G
基于MIMO系统的SDR-AltMin混合预编码算法matlab性能仿真
基于MIMO系统的SDR-AltMin混合预编码算法通过结合半定松弛和交替最小化技术,优化大规模MIMO系统的预编码矩阵,提高信号质量。Matlab 2022a仿真结果显示,该算法能有效提升系统性能并降低计算复杂度。核心程序包括预编码和接收矩阵的设计,以及不同信噪比下的性能评估。
26 3
|
12天前
|
机器学习/深度学习 算法 数据挖掘
提高时钟置换算法的性能
【10月更文挑战第25天】通过上述一种或多种方法的综合应用,可以在不同程度上提高时钟置换算法的性能,使其更好地适应各种复杂的系统环境和应用场景,提高虚拟内存管理的效率和系统的整体性能。
31 5
|
14天前
|
缓存 监控 测试技术
如何利用浏览器的缓存来优化网站性能?
【10月更文挑战第23天】通过以上多种方法合理利用浏览器缓存,可以显著提高网站的性能,减少网络请求,加快资源加载速度,提升用户的访问体验。同时,要根据网站的具体情况和资源的特点,不断优化和调整缓存策略,以适应不断变化的业务需求和用户访问模式。
57 7
|
17天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
18 3
|
20天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
65 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
1月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
57 4