從CPU級操作到數據庫接口,
緩存急劇加速了處理。 緩存無效 - 確定何時刪除緩存數據 - 是一個複雜的挑戰。這篇文章解決了一個更簡單,但陰險的緩存問題。
>這個問題,潛伏了18個月,只有在用戶偏離建議使用模式時才浮出水面。 該問題源於我組織中的自定義機器學習(ML)框架(基於Scikit-Learn)。 該框架經常訪問多個數據源,因此需要一個緩存層進行性能和成本優化(降低大Query出口成本)。
最初使用lru_cache
>,但是在開發過程中經常訪問的靜態數據需要持續的緩存。 使用SQLITE的Python庫DiskCache
>是為了與我們的32個過程環境和Pandas DataFrames(最高500MB)的兼容性而選擇。 在內存中訪問lru_cache
的頂部。
>
>我們的編碼標準要求在任何處理後創建新的數據范圍。 但是,一些用戶出於習慣而使用,直接修改了被緩存的對象。 這不僅改變了他們的直接結果,而且還破壞了緩存的數據,影響了後續的請求。
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中文網其他相關文章!