3.3 提高Python运行速度(小技巧)
3.3.1 通过公式计算
如果在计算时,能使用公式计算出最后的结果,那对于运行效率上来说就是降维打击了。在一些特殊场景中,我们不必傻乎乎的利用循环进行计算,尝试使用公式计算对于速度的提升将是飞越性的。
速度对比_公式计算
from mdTools import ftDecTimeIt
import numpy as np
array = np.random.random(1_0000_0000)
@ftDecTimeIt(1)
def slow():
s = 0
for _ in range(1, 1_0000_0001):
s += _
@ftDecTimeIt(1)
def fast():
s = (1 + 1_0000_0000) * 1_0000_0000 / 2
slow()
fast()
函数 slow 运行 1 次的总耗时为:5.0604 秒
函数 fast 运行 1 次的总耗时为:0.0000 秒
3.3.2 在函数中导入模块
虽然导入模块有时候是必不可少的,但是其实导入模块也是需要花费时间的,当我们在制作模块而需要被其它模块导入时,由于被导入模块通常最上方导入了该模块其它函数或类的依赖模块,于是在被其它模块导入时,某些不必要的模块也会被导入。
为了避免这种情况,其实我们可以在函数内部导入模块,而非在模块最上方导入。
3.3.3 使用列表推导式
Python中的列表推导式为我们提供了更简短的语法,甚至只需要一行代码就可以实现各种复杂的可迭代对象。我们可以使用列表推导式生成我们想要的列表、元组,甚至字典等。
通过列表推导式不仅可以提高代码编写效率,也能提高运行效率。
速度对比_列表推导式
from mdTools import ftDecTimeIt
@ftDecTimeIt(10000)
def slow():
a = []
for _ in range(10000):
if _ % 2 == 0:
a.append(_)
@ftDecTimeIt(10000)
def fast():
a = [x for x in range(10000) if x % 2 == 0]
slow()
fast()
函数 slow 运行 10000 次的总耗时为:7.2413 秒
函数 fast 运行 10000 次的总耗时为:5.5238 秒
3.3.4 使用 f-Strings连接字符串
我们已经知道将字符串进行串联可能会使程序变慢。尤其是使用’+’进行拼接。并且,‘+’只能拼接字符串类型的数据,遇到其它类型时必须转换成str才能正常拼接。
一个比较好的解决方案是使用f-Strings,通过f-strings拼接可以自动将其他类型转换成字符串类型,并且速度要比‘+’拼接快。
速度对比_f-strgings
from mdTools import ftDecTimeIt
@ftDecTimeIt(100_0000)
def slow():
a = {'name': 'zhangsan', 'gender': 'man', 'age': 18}
s = '我的名字是:' + a['name'] + ' 性别是:' + a['gender'] + ' 年龄是:' + str(a['age'])
return s
@ftDecTimeIt(100_0000)
def fast():
a = {'name': 'zhangsan', 'gender': 'man', 'age': 18}
s = f"我的名字是:{a['name']} 性别是:{a['gender']} 年龄是:{a['age']}"
return s
print(slow())
print(fast())
函数 slow 运行 1000000 次的总耗时为:0.7570 秒
我的名字是:zhangsan 性别是:man 年龄是:18
函数 fast 运行 1000000 次的总耗时为:0.5284 秒
我的名字是:zhangsan 性别是:man 年龄是:18
3.3.5 从集合中检查
如果要在一个非常大的列表中判断某个元素是否存在,那么可以先将其转换成集合,然后再在该集合中判断是否存在目标元素。这样将会提高运行效率。
速度对比_检查元素
from mdTools import ftDecTimeIt
import numpy as np
lst = np.random.random(10000)
st = set(lst)
@ftDecTimeIt(100000)
def slow():
if 0 in lst:
pass
@ftDecTimeIt(100000)
def fast():
if 0 in st:
pass
slow()
fast()
函数 slow 运行 100000 次的总耗时为:0.7620 秒
函数 fast 运行 100000 次的总耗时为:0.0110 秒
3.3.6 使用局部变量
全局变量会一直保存在内存之中,而局部变量在函数调用完毕后马上销毁。
速度对比_使用局部变量
from mdTools import ftDecTimeIt
a = 'a'
@ftDecTimeIt(1)
def slow():
lst = []
for _ in range(10000000):
lst.append(a)
@ftDecTimeIt(1)
def fast():
b = 'b'
lst = []
for _ in range(10000000):
lst.append(b)
slow()
fast()
函数 slow 运行 1 次的总耗时为:0.9645 秒
函数 fast 运行 1 次的总耗时为:0.8803 秒
3.3.7 减少通过‘.’访问属性
速度对比_访问属性
from mdTools import ftDecTimeIt
@ftDecTimeIt(100_0000)
def slow():
lowerlist = ['i', 'am', 'a', 'bad', 'boy', 'am', 'a', 'bad', 'boy', 'am', 'a', 'bad', 'boy']
upperlist = []
for word in lowerlist:
upperlist.append(word.upper())
@ftDecTimeIt(100_0000)
def fast():
lowerlist = ['i', 'am', 'a', 'bad', 'boy', 'am', 'a', 'bad', 'boy', 'am', 'a', 'bad', 'boy']
up = str.upper
upperlist = []
ap = upperlist.append
for word in lowerlist:
ap(up(word))
slow()
fast()
函数 slow 运行 1000000 次的总耗时为:1.5311 秒
函数 fast 运行 1000000 次的总耗时为:1.3696 秒
3.3.8 创建列表和字典
使用[]和{}来创建列表和字典相比使用list()和dict{}运行更加高效,因为使用list()和dict{}来创建对象时需要调用一个附加函数。
速度对比_创建list
from mdTools import ftDecTimeIt
@ftDecTimeIt(1000_0000)
def slow():
lst = list('123')
@ftDecTimeIt(1000_0000)
def fast():
lst = [1, 2, 3]
slow()
fast()
函数 slow 运行 10000000 次的总耗时为:2.7894 秒
函数 fast 运行 10000000 次的总耗时为:1.3917 秒
速度对比_创建dict
from mdTools import ftDecTimeIt
@ftDecTimeIt(1000_0000)
def slow():
dct = dict(['12', '34'])
@ftDecTimeIt(1000_0000)
def fast():
dct = {'1': '2', '3': '4'}
slow()
fast()
函数 slow 运行 10000000 次的总耗时为:6.1273 秒
函数 fast 运行 10000000 次的总耗时为:1.7276 秒