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)

TAG:Python | 缓存 | 性能优化 |