20 行 python 代碼實現函數的 cache 功能
原理
給需要緩存的函數加一個修飾器。
第一次調用時,正常執行,並緩存計算結果。
使用相同的參數,第二次調用時,不執行,直接載入計算結果。
使用場景
項目大了,代碼質量總是難以控制。
再也不用擔心大家反覆調用同一個函數導致性能低下了。
在某個數據分析項目里,運行時間縮短了 60%
數據分析的早期演算法驗證時,
修改幾個參數就要從頭全部跑一遍,費時間。
手動保存一些中間結果,繁瑣、易出 bug。
完整代碼及 demo
# -*- coding: utf-8 -*-nimport hashlibnimport osnimport picklennncache_root_dir = cachennnif not os.path.exists(cache_root_dir):n os.makedirs(cache_root_dir)nnndef md5(s):n m = hashlib.md5()n m.update(s)n return m.hexdigest()nnndef cache_key(f, *args, **kwargs):n s = %s-%s-%s % (f.__name__, str(args), str(kwargs))n return os.path.join(cache_root_dir, %s.dump % md5(s))nnndef cache(f):n def wrap(*args, **kwargs):n fn = cache_key(f, *args, **kwargs)n if os.path.exists(fn):n print loading cachen with open(fn, rb) as fr:n return pickle.load(fr)nn obj = f(*args, **kwargs)n with open(fn, wb) as fw:n pickle.dump(obj, fw)n return objnn return wrapnnn@cachendef add(a, b):n return a + bnnnif __name__ == __main__:n print add(3, 4)n print add(3, 4)n print add(8, 4)n print add(4, 8)n
運行結果:
$ python func_cache.pyn7nloading cachen7n12n12n
細節說明
這個版本,緩存在文件里。
函數名+所有傳參拼接為 string,取其 md5 作為文件名。
根據文件名判斷緩存是否存在。
這個版本,適合於場景 2 -- 數據分析的早期演算法驗證。
針對場景 1,建議緩存在內存里。
用一個字典類型的全局變數作為緩存。
函數名 + 傳參的 md5 作為 key。
推薦閱讀:
※IT故障頻繁造成飛機延誤 雲智慧透視寶快速故障溯源有效降低業務損失
※RAIL,以用戶為核心的性能模型
※通過三次優化,我將gif載入優化了16.9%
※如何精簡Unity中使用的字體文件
※Unity載入模塊深度解析(Shader)