对那些需要高频率以相同参数运行的函数,或者需要重复加载的数据,如果每次都执行函数完整的代码,或者重复从文件加载数据进行处理,会试程序运行效率变低。改善效率可通过使用内存缓存或磁盘缓存的形式,从而提高代码效率。
适用条件:函数经常需要以相同输入参数执行。
效果:以参数args执行函数时,如果内存缓存中记录了相同输入参数的运行结果,则函数直接从缓存中返回结果,不在执行函数体的代码。
举例:
- import functools
-
- SIZE_CACHE = 1 # 缓存大小
-
- @functools.lru_cache(SIZE_CACHE)
- def my_add(a, b):
- print("函数体被执行")
- return a+b
-
-
- if __name__ == "__main__":
- print("第一次运行结果。缓存为空,需要函数体")
- print(my_add(1, 1), '\n')
- print("第二次运行结果。由于缓存已有a=1,b=1的结果,所以函数体不执行")
- print(my_add(1, 1), '\n')
-
- print("第三次运行结果。缓存中没有a=1,b=2的结果,函数体要执行")
- print(my_add(1, 2), '\n')
-
- print("第四次运行结果。缓存中已变为a=1,b=2的结果,a=1,b=1的缓存已被覆盖,所以函数体执行")
- print(my_add(1, 1), '\n')
运行结果:
- 第一次运行结果。缓存为空,需要函数体
- 函数体被执行
- 2
-
- 第二次运行结果。由于缓存已有a=1,b=1的结果,所以函数体不执行
- 2
-
- 第三次运行结果。缓存中没有a=1,b=2的结果,函数体要执行
- 函数体被执行
- 3
-
- 第四次运行结果。缓存中已变为a=1,b=2的结果,a=1,b=1的缓存已被覆盖,所以函数体执行
- 函数体被执行
- 2
如果需要经常从文件读取数据进行预处理,可以将预处理结果存到磁盘缓存中,这样下次可直接读取磁盘缓存的结果,省去数据处理的实际。磁盘缓存有很多第三方库,其中一个为diskcache
适用条件:频发加载数据,比如机器学习加载数据集。
效果:可提高数据加载速度。
举例:
- from diskcache import FanoutCache
- import time
-
- my_cache = FanoutCache(r"D:/my_cache",
- shards=64, # 将缓存文件自动分成64个部分
- timeout=1,
- size_limit=3e11, # 每个部分文件的文件最大占用空间
- # disk_min_file_size=2**20, # 文件最小尺寸
- )
-
-
- @my_cache.memoize(typed=True)
- def data_process(a=1):
- # 加载,处理文件数据,生产数据data, 假设生产的数据为[1, 2, 3]
- data = [1, 2, 3]
- time.sleep(3)
- return data
-
- if __name__ =='__main__':
- t1 = time.time()
- data_process(a=2)
- delt_t = time.time() - t1
- print("第一次运行使用时间: ", delt_t, '\n')
-
- t1 = time.time()
- data_process(a=2)
- delt_t = time.time() - t1
- print("第二次运行使用时间: ", delt_t, '\n')
-
-
运行结果如下。对比可知,缓存之后,函数体代码并未执行,返回的是磁盘缓存的数据。
- 第一次运行使用时间: 3.0158493518829346
-
- 第二次运行使用时间: 0.0
保存的缓存文件如下,可见数据被缓存成了64个文件夹保存:
