废话不多说
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 中字符串是不可变对象,它会申请一块内存空间,将a和b分别复制到该新申请的内存空间中。
因此,如果要拼接 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可以将 Python 函数 JIT 编译为机器码执行,大大提高代码运行速度。
numba
关于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.
本文来自博客园,作者:FilexHu,转载请注明原文链接:https://www.cnblogs.com/filexhu/articles/15176926.html
加速CPython!
在今年2021 Python语言峰会上,Guido Van Rossum在表示:他打算在2022年10月发布3.11版本时将快CPython的速度提高1倍。在接下来的四年里,他的目标是将CPython的速度提高到原来的5倍。
浙公网安备 33010602011771号