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,五一前忘记倒掉壶里的茶水了,都长毛了!!

相关文章
|
数据采集 存储 Web App开发
Python爬虫库性能与选型实战指南:从需求到落地的全链路解析
本文深入解析Python爬虫库的性能与选型策略,涵盖需求分析、技术评估与实战案例,助你构建高效稳定的数据采集系统。
855 0
|
存储 机器学习/深度学习 缓存
性能最高提升7倍?探究大语言模型推理之缓存优化
本文探讨了大语言模型(LLM)推理缓存优化技术,重点分析了KV Cache、PagedAttention、Prefix Caching及LMCache等关键技术的演进与优化方向。文章介绍了主流推理框架如vLLM和SGLang在提升首Token延迟(TTFT)、平均Token生成时间(TPOT)和吞吐量方面的实现机制,并展望了未来缓存技术的发展趋势。
4064 13
性能最高提升7倍?探究大语言模型推理之缓存优化
|
机器学习/深度学习 数据采集 算法
Python AutoML框架选型攻略:7个工具性能对比与应用指南
本文系统介绍了主流Python AutoML库的技术特点与适用场景,涵盖AutoGluon、PyCaret、TPOT、Auto-sklearn、H2O AutoML及AutoKeras等工具,帮助开发者根据项目需求高效选择自动化机器学习方案。
1532 1
|
网络协议 API Python
解析http.client与requests在Python中的性能比较和改进策略。
最后,需要明确的是,这两种库各有其优点和适用场景。`http.client` 更适合于基础且并行的请求,`requests` 则因其易用且强大的功能,更适用于复杂的 HTTP 场景。对于哪种更适合你的应用,可能需要你自己进行实际的测试来确定。
312 10
|
网络协议 API 开发者
分析http.client与requests在Python中的性能差异并优化。
合理地选择 `http.client`和 `requests`库以及在此基础上优化代码,可以帮助你的Python网络编程更加顺利,无论是在性能还是在易用性上。我们通常推荐使用 `requests`库,因为它的易用性。对于需要大量详细控制的任务,或者对性能有严格要求的情况,可以考虑使用 `http.client`库。同时,不断优化并管理员连接、设定合理超时和重试都是提高网络访问效率和稳定性的好方式。
305 19
|
数据采集 测试技术 C++
无headers爬虫 vs 带headers爬虫:Python性能对比
无headers爬虫 vs 带headers爬虫:Python性能对比
|
缓存 并行计算 数据处理
全面提升Python性能的十三种优化技巧
通过应用上述十三种优化技巧,开发者可以显著提高Python代码的执行效率和性能。每个技巧都针对特定的性能瓶颈进行优化,从内存管理到并行计算,再到使用高效的数值计算库。这些优化不仅能提升代码的运行速度,还能提高代码的可读性和可维护性。希望这些技巧能帮助开发者在实际项目中实现更高效的Python编程。
1109 22
|
10月前
|
机器学习/深度学习 算法 机器人
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
415 8
|
10月前
|
机器学习/深度学习 算法 自动驾驶
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
469 8
|
10月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
793 0

推荐镜像

更多