前言
今天学习了一下利用装饰器和字典缓存来优化代码的性能,同时利用时间测量技术直观的展示它带来了多大的性能优化。
应用场景
这只是入门,学习一下调用相同参数方法的优化方案。
主干
先做一个简单的装饰器,定义一个名为caches
的字典用于缓存我们需要的东西,即方法func
: 参数args
,并将这个方法调用这个参数的结果,以缓存形式存储在字典里。
如果caches
里没有此键值对,就会调用func
方法,并将结果保存在缓存中。如果有相应的键值对,就立即返回此函数的结果。
def cache(func):
caches = {}
def wrapper(*args):
if args not in caches:
caches[args] = func(*args)
return caches[args]
return wrapper
再写一个最简单的测试函数,并声明刚刚写的装饰器cache
,功能的话,找下参数范围内的所有偶数吧:
@cache
def funTest(arg):
nums = [x for x in range(arg) if x % 2 == 0]
然后,再写个时间测量函数,每次调用func
方法,并传入args
参数后,打印消耗的时间:
def get_time(func, *args):
start_time = time.time()
result = func(*args)
end_time = time.time()
print("耗时:", end_time - start_time)
return result
测试
到这里,我们的入门代码基本就完成了,简单分两次调用一下,就找找3千万以内的所有偶数吧:
get_time(funTest, 30000000)
time.sleep(1)
get_time(funTest, 30000000)
效果截图:
可以发现第一次找3千万以内的所有偶数,用了差不多1.55秒,但是第二次找,瞬间就可以找完,这就是性能的优化。
完整代码
# -*- coding:utf-8 -*-
# author: YP
# date:2023/10/10
import time
def cache(func):
caches = {}
def wrapper(*args):
if args not in caches:
caches[args] = func(*args)
return caches[args]
return wrapper
@cache
def funTest(arg):
nums = [x for x in range(arg) if x % 2 == 0]
def get_time(func, *args):
start_time = time.time()
result = func(*args)
end_time = time.time()
print("耗时:", end_time - start_time)
return result
get_time(funTest, 30000000)
time.sleep(1)
get_time(funTest, 30000000)