Pythonキャッシュ変動値

Barbara Streisand
リリース: 2025-01-26 16:13:10
オリジナル
932 人が閲覧しました

Python Caching mutable values

キャッシュにより、CPU レベルの操作からデータベース インターフェイスに至るまで、処理が大幅に高速化されます。 キャッシュの無効化、つまりキャッシュされたデータをいつ削除するかを決定することは、複雑な課題です。この投稿では、単純ではあるが潜伏性のあるキャッシュの問題に対処します。

この問題は 18 か月間潜んでいましたが、ユーザーが推奨される使用パターンから逸脱した場合にのみ表面化しました。 この問題は、私の組織内のカスタム機械学習 (ML) フレームワーク (scikit-learn 上に構築) に起因していました。 このフレームワークは複数のデータ ソースに頻繁にアクセスするため、パフォーマンスとコストの最適化(BigQuery の下りコストの削減)のためにキャッシュ レイヤーが必要になります。

当初は lru_cache が使用されていましたが、開発中に頻繁にアクセスされる静的データには永続的なキャッシュが必要でした。 SQLite を使用する Python ライブラリである DiskCache は、そのシンプルさと 32 プロセス環境および Pandas DataFrames (最大 500MB) との互換性のために選択されました。 メモリ内アクセスのために lru_cache レイヤーが最上位に追加されました。

この問題は、より多くのユーザーがフレームワークを実験するにつれて明らかになりました。 ランダムに不正確な結果が報告され、一貫して再現することが困難でした。 根本原因: キャッシュされた Pandas DataFrame のインプレース変更。

私たちのコーディング標準では、処理後に新しい DataFrame を作成することが規定されています。 ただし、一部のユーザーは習慣で inplace=True を使用し、キャッシュされたオブジェクトを直接変更していました。 これにより、直接の結果が変更されただけでなく、キャッシュされたデータも破損し、後続のリクエストに影響を及ぼしました。

説明のために、辞書を使用したこの単純化された例を考えてみましょう。

<code class="language-python">from functools import lru_cache
import time
import typing as t
from copy import deepcopy

@lru_cache
def expensive_func(keys: str, vals: t.Any) -> dict:
    time.sleep(3)
    return dict(zip(keys, vals))


def main():
    e1 = expensive_func(('a', 'b', 'c'), (1, 2, 3))
    print(e1)

    e2 = expensive_func(('a', 'b', 'c'), (1, 2, 3))
    print(e2)

    e2['d'] = "amazing"

    print(e2)

    e3 = expensive_func(('a', 'b', 'c'), (1, 2, 3))
    print(e3)


if __name__ == "__main__":
    main()</code>
ログイン後にコピー

lru_cache はコピーではなく参照を提供します。 e2 を変更すると、キャッシュされたデータが変更されます。

解決策:

この解決策には、キャッシュされたオブジェクトのディープ コピーを返すことが含まれます。

<code class="language-python">from functools import lru_cache, wraps
from copy import deepcopy

def custom_cache(func):
    cached_func = lru_cache(func)

    @wraps(func)
    def _wrapper(*args, **kwargs):
        return deepcopy(cached_func(*args, **kwargs))

    return _wrapper</code>
ログイン後にコピー

これにより、わずかなオーバーヘッド (データの重複) が追加されますが、データの破損は防止されます。

重要なポイント:

  • lru_cache の参照動作をより深く理解します。
  • コーディング標準に準拠すると、バグが最小限に抑えられます。
  • 実装におけるベスト プラクティスからのユーザーの逸脱を考慮します。 堅牢性はしばしば優雅さよりも優先されます。

以上がPythonキャッシュ変動値の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート