首頁 > 後端開發 > Python教學 > Python緩存可變值

Python緩存可變值

Barbara Streisand
發布: 2025-01-26 16:13:10
原創
928 人瀏覽過

Python Caching mutable values

從CPU級操作到數據庫接口,

緩存急劇加速了處理。 緩存無效 - 確定何時刪除緩存數據 - 是一個複雜的挑戰。這篇文章解決了一個更簡單,但陰險的緩存問題。

>

這個問題,潛伏了18個月,只有在用戶偏離建議使用模式時才浮出水面。 該問題源於我組織中的自定義機器學習(ML)框架(基於Scikit-Learn)。 該框架經常訪問多個數據源,因此需要一個緩存層進行性能和成本優化(降低大Query出口成本)。

最初使用lru_cache>,但是在開發過程中經常訪問的靜態數據需要持續的緩存。 使用SQLITE的Python庫DiskCache>是為了與我們的32個過程環境和Pandas DataFrames(最高500MB)的兼容性而選擇。 在內存中訪問lru_cache的頂部。

> 隨著越來越多的用戶嘗試該框架,問題出現了。 報告了隨機錯誤的結果,難以持續繁殖。 根本原因:緩存的Pandas DataFrames的原位修改。

>

>我們的編碼標準要求在任何處理後創建新的數據范圍。 但是,一些用戶出於習慣而使用

,直接修改了被緩存的對象。 這不僅改變了他們的直接結果,而且還破壞了緩存的數據,影響了後續的請求。 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_cachee2解決方案:

該解決方案涉及返回緩存對象的深副本:>

這增加了一個小開銷(數據重複),但可以防止數據損壞。 >

鑰匙要點:
<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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板