深度盘点:Python 7种提效增速的技巧

x33g5p2x  于2021-10-31 转载在 Python  
字(2.2k)|赞(0)|评价(0)|浏览(543)

在工作中,我们常常面临着代码提速优化问题,本文就为大家介绍几种Python常用的提速技巧。
优化原则:
1.先保证代码可以正确运行,再进行性能优化
2.优化的选择通常是牺牲空间换取时间,所有我们需要权衡代价
3.着重优化代码耗时的部分,通篇优化通常会降低代码的可读性

0 定义耗时装饰器

  1. # 可监控程序运行时间
  2. import time
  3. def clock(func):
  4. def wrapper(*args, **kwargs):
  5. start_time = time.time()
  6. result = func(*args, **kwargs)
  7. end_time = time.time()
  8. print("共耗时: %s秒" % round(end_time - start_time, 2))
  9. return result
  10. return wrapper

1 避免使用全局变量

  1. start_time = time.time()
  2. size = 10000
  3. for x in range(size):
  4. for y in range(size):
  5. z = x * y
  6. end_time = time.time()
  7. print('共耗时:%s秒' % round(end_time - start_time, 2))
  8. # 共耗时:11.78秒,不推荐
  1. # 使用局部变量
  2. @clock
  3. def multiplication():
  4. size = 10000
  5. for x in range(size):
  6. for y in range(size):
  7. z = x * y
  8. multiplication()
  9. # 共耗时: 5.5秒,提速50%

2 避免访问方法(函数)的属性,尽量使用from X import X

  1. import math
  2. @clock
  3. def computeSqrt():
  4. result = []
  5. for i in range(10000000):
  6. # math方法访问sqrt属性
  7. result.append(math.sqrt(i))
  8. computeSqrt()
  9. # 不推荐,共耗时: 2.09秒
  1. # 使用from X import X,直接访问sqrt
  2. from math import sqrt
  3. @clock
  4. def computeSqrt():
  5. result = []
  6. for i in range(10000000):
  7. result.append(sqrt(i))
  8. computeSqrt()
  9. # 推荐,共耗时: 1.75秒

在【1】中我们讲到,局部变量的查找会比全局变量更快,因此对于频繁访问的变量append,通过将其改为局部变量可以加速运行。

  1. from math import sqrt
  2. @clock
  3. def computeSqrt():
  4. result = []
  5. # 赋值给局部变量
  6. append = result.append
  7. for i in range(10000000):
  8. append(sqrt(i))
  9. computeSqrt()
  10. # 推荐,共耗时: 1.45秒

3 遍历优化

  1. # 使用while进行遍历
  2. @clock
  3. def circulate():
  4. i = 0
  5. li = []
  6. append = li.append
  7. while i < 10000000:
  8. append(i*2)
  9. i += 1
  10. return li
  11. circulate()
  12. # 不推荐,共耗时:1.48秒
  1. @clock
  2. def circulate():
  3. li = []
  4. append = li.append
  5. # 使用for代替while
  6. for i in range(10000000):
  7. append(i*2)
  8. return li
  9. circulate()
  10. # for优于while,共耗时:1.09秒
  1. @clock
  2. def circulate():
  3. # 使用列表推导式
  4. return [i*2 for i in range(10000000)]
  5. circulate()
  6. # 推荐列表推导式,共耗时:0.88秒。但不适用于复杂计算。

4 减少内层for循环的计算

  1. from math import sqrt
  2. @clock
  3. def inner():
  4. size = 10000
  5. for x in range(size):
  6. for y in range(size):
  7. # 相当于在重复计算sqrt(x)
  8. z = sqrt(x) + sqrt(y)
  9. inner()
  10. # 不推荐,共耗时:19.00秒
  1. from math import sqrt
  2. @clock
  3. def inner():
  4. size = 10000
  5. for x in range(size):
  6. # 只计算一次sqrt(x),然后将它存了起来
  7. sqrt_x = sqrt(x)
  8. for y in range(size):
  9. z = sqrt_x + sqrt(y)
  10. inner()
  11. # 推荐,共耗时:10.22秒

5 使用Numpy数据类型进行运算

因为Numpy底层是用C语言实现的,而Python这种脚本语言相比C/C++这种编译语言在效率和性能方面有天然劣势,所以我们可以引入Numpy包,对数据进行类型转换后再进行计算。

  1. import numpy as np
  2. li = [i for i in range(10000000)]
  3. @clock
  4. def npSpeed():
  5. # 使用Python方法
  6. sum(li)
  7. npSpeed()
  8. # 共耗时0.79秒
  1. import numpy as np
  2. li = np.array([i for i in range(100000000)])
  3. @clock
  4. def npSpeed():
  5. # 使用Numpy方法
  6. np.sum(li)
  7. npSpeed()
  8. # 共耗时0.11秒,速度约是Python的8倍

Numpy的优势在数据量越大时,体现的也会更加明显。所以在机器学习与深度学习项目任务中,Numpy的使用就非常频繁。

相关文章