Python キャッシュ アーティファクト cachetools: プログラムのパフォーマンスを向上させる強力なツールです。この記事では、そのキャッシュ アルゴリズムについて詳しく説明します


序文

春の山はまるで黄色く、万燕の枝は枝でいっぱいで、
イェイェのそよ風が世界で踊っています。

1. cachetools ライブラリの紹介と詳しい使い方

1-1. 定義

cachetools : さまざまなキャッシュ アルゴリズムの実装を提供するサードパーティの Python ライブラリです。キャッシングは、計算結果を一時的に保存して、後続の計算で同じ計算を繰り返さないようにするために使用される手法です。キャッシュを使用すると、アプリケーションのパフォーマンスと応答性を向上させることができます。

1-2. 複数のキャッシュ戦略

cachetools は、次の一般的なキャッシュ戦略を提供します

  • 使用頻度が最も低い (LRU) : この方法では、使用頻度が最も低いエントリが削除されます。新しいエントリ用のスペースを確保する必要がある場合、使用頻度の最も低いエントリが削除されます。これは、ほとんどのシナリオで機能する一般的なキャッシュ戦略です。

  • 最近使用された (MRU) : この戦略では、最近使用されたエントリが削除されます。新しいエントリ用のスペースを確保する必要がある場合、最近使用されたエントリが削除されます。この戦略は、最近アクセスされたデータが再びアクセスされる可能性が低い場合など、いくつかの特別なシナリオに適しています。

  • ランダム置換 (RR) : この戦略は、エントリをランダムに削除します。新しいエントリのためのスペースを作るときが来ると、削除するエントリがランダムに選択されます。この戦略は実装が簡単ですが、パフォーマンスが比較的低くなります。

  • 先入れ先出し (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. エラーの概要

3-1、TypeError: ハッシュできない型: 'dict'

エラー元:cachetoolsのキャッシュのキー(キー)に辞書を直接使いたいのですが、エラーになります。

このエラーは、Python では辞書 (dict) 型がハッシュ可能 (ハッシュ不可) ではないため、辞書を直接 cachetools キャッシュのキー (キー) として使用できないためです。これを修正するには、ディクショナリを文字列 (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 はキャッシュにデータがあるかどうかを確認します。キャッシュにデータがある場合、キャッシュされたデータが直接返されるため、リクエスト インターフェイスの繰り返しが回避され、プログラムのパフォーマンスが向上します。


要約する

ええと、メーデーの前にポットにお茶を注ぐのを忘れていました。毛むくじゃらです! !

おすすめ

転載: blog.csdn.net/weixin_42475060/article/details/130502149
おすすめ