废话不多说

1. 尽量做到不适用全局变量

  Python中全局变量和局部变量实现方式并不相同,全局范围内定义的代码和定义在函数中的代码相比,运行速度会慢不少。

通过将脚本语句放入到函数中,带来近乎一倍的速度提升(根据自己机器配置不同运行耗时也不同)。如下:

 

 1 @PythonIDE    : PyCharm
 2 @Author       : Felix.Hu
 3 @User         : Filex.Hu
 4 @Date         : 2021/8/23 15:30
 5 @Description  : --
 6 =====================================================
 7 @Change Activity
 8 =====================================================
 9 """
10 # 不推荐写法。代码耗时:9.15秒
11 from datetime import datetime
12 
13 start_time = datetime.now()
14 size = 10000
15 for x in range(size):
16     for y in range(size):
17         z = x + y
18 print(f'执行完毕,耗时:{datetime.now()-start_time}')

 

# 推荐写法 耗时04.52
 1 from datetime import datetime
 2 def main():
 3     """
 4     定义到函数中,以减少全局变量使用
 5     :return:
 6     """
 7     start_time = datetime.now()
 8     size = 10000
 9     for x in range(size):
10         for y in range(size):
11             z = x + y
12     print(f'执行完毕,耗时:{datetime.now()-start_time}')

 

2.尽量避免模块和函数属性访问

  这个方法提速不是很明显,经过测试有的模块导入方式: import 模块名 甚至比 from 模块名 import 接口名  速度还要快几秒。。。所以可以忽略,不过在使用一些大量数学计算的模块时还是要使用from xxx import xxx比较好些。

3.避免类内属性访问

  原理同方法1,可自行测试。

  访问self._value的速度会比访问一个局部变量更慢一些。把需要频繁访问的类内属性赋值给一个局部变量,可以提升代码运行速度。

  尤其是这个属性在循环内被使用时,提速效果更明显。上面所说需要频繁访问就是指在循环内被使用。

4.交换值时不使用中间变量 

  这个效果也不是很明显,但有总比没有的好,要什么自行车啊。。。

# 不推荐写法,代码耗时:0.049950秒
1 def main():
2     size = 1000000
3     for _ in range(size):
4         a = 3
5         b = 5
6         temp = a
7         a = b
8         b = temp

 

# 推荐写法,代码耗时:0.043992秒
1 def main():
2     size = 1000000
3     for _ in range(size):
4         a = 3
5         b = 5
6         a, b = b, a # 不借助中间变量

5. 字符串拼接用join而不是"+"
  当使用a + b拼接字符串时,由于 Python 中字符串是不可变对象,它会申请一块内存空间,将ab分别复制到该新申请的内存空间中。
因此,如果要拼接 n 个字符串,会产生 n-1 个中间结果,每产生一个中间结果都需要申请和复制一次内存,严重影响运行效率。
而使用join()拼接字符串时,会首先计算出需要申请的总的内存空间,然后一次性地申请所需内存,并将每个字符串元素复制到该内存中去。

# 不推荐写法,代码耗时:12.348855秒

 1 from datetime import datetime
 2 import string
 3 from typing import List
 4 
 5 
 6 def concat_string(string_list: List[str]) -> str:
 7     result = ''
 8     for str_i in string_list:
 9         result += str_i
10     return result
11 
12 
13 def main():
14     string_list = list(string.ascii_letters * 100)
15     for _ in range(10000):
16         result = concat_string(string_list)

 


# 推荐写法,代码耗时:0.381799秒

 1 import string
 2 from typing import List
 3 
 4 
 5 def concat_string(string_list: List[str]) -> str:
 6   return ''.join(string_list) # 使用 join 而不是 +
 7 
 8 
 9 def main():
10   string_list = list(string.ascii_letters * 100)
11   for _ in range(10000):
12     result = concat_string(string_list)

 

6.用for循环代替while循环:Python中for循环要比while循环快

# 不推荐写法。代码耗时:07.634586秒

 1 from datetime import datetime
 2 
 3 
 4 def the_sum(size: int) -> int:
 5     sum_ = 0
 6     i = 0
 7     while i < size:
 8         sum_ += i
 9         i += 1
10     return sum_
11 
12 
13 def main():
14     size = 10000
15     for _ in range(size):
16         sum_ = the_sum(size)
17 
18 
19 start_time = datetime.now()
20 main()
21 print(f'执行完毕,共耗时:{datetime.now() - start_time}')

 

 

# 推荐写法。代码耗时:4.849182秒

 1 from datetime import datetime
 2 
 3 
 4 def the_sum(size: int) -> int:
 5     sum_ = 0
 6     for i in range(size): # for 循环代替 while 循环
 7         sum_ += i
 8     return sum_
 9 
10 
11 def main():
12     size = 10000
13     for _ in range(size):
14         sum_ = the_sum(size)
15 
16 
17 start_time = datetime.now()
18 main()
19 print(f'执行完毕,共耗时:{datetime.now() - start_time}')

 



另外:使用隐式for循环代替显式for循环 效果更明显

 

# 推荐写法。代码耗时:1.886076秒def the_sum(size: int) -> int:    # 隐式 for 循环代替显式 for 循环    return sum(range(size))def main():    size = 10000    for _ in range(size):        sum = the_sum(size)

7.使用numba.jit   
  numba
可以将 Python 函数 JIT 编译为机器码执行,大大提高代码运行速度。
关于numba的更多信息见下面的主页:http://numba.pydata.org/numba.pydata.org

8. 尽量使用Python内置的数据结构
  不要自己去实现新的数据结构,python的内置数据结构底层都是c实现的。除非你用c去实现新的数据类型,再加载到python中,想想就刺激。。。

参考资料:
  • https://wiki.python.org/moin/TimeComplexity

  • 张颖 & 赖勇浩. 编写高质量代码:改善Python程序的91个建议. 机械工业出版社, ISBN: 9787111467045, 2014.

 

 

posted on 2021-08-23 17:39  FilexHu  阅读(329)  评论(0)    收藏  举报