翻译自 7 Habits to Improve The Performance of Python Programs

Python在性能方面并不擅长,但通过一些习惯,可以提高程序性能并避免一些不必要的资源浪费。

1.使用局部变量

尝试使用局部变量而不是全局变量,可以使代码易于维护,并有助于提高性能节省内存。

用局部变量替换模块命名空间中的变量,例如ls = os.linesep。 一方面,它可以提高程序性能,因为局部变量的搜索速度更快; 另一方面,冗长的模块变量可以用短标识符替换,以提高可读性。

2.减少函数调用的次数

在确定对象类型时,最好使用isinstance(),使用id()次优,最差情况则是使用type()进行比较。

1
2
3
4
# Determine whether the variable num is an integer type
type(num) == type(0) # 1.call the function three times
type(num) is type(0) # 2.identity comparison
isinstance(num,(int)) # 3.call the function once

也不要将重复操作作为参数放在循环中,以避免重复计算。

1
2
3
4
5
6
7
# 1.Each loop needs to re-execute len(a)
while i < len(a):
statement
# 2.Only execute len(a) once
m = len(a)
while i < m:
statement

要在模块 X 中使用函数或对象 Y ,您应该直接使用 from X import Y 而不是直接使用import XX.Y 。这样的话,当使用Y时,可以减少一次查询(解释器不必首先找到X模块,然后在X模块的字典中查找Y)。

3.使用映射替换条件搜索

映射的搜索速度(例如 dict )比条件语句(例如 if 等)快得多。 并且Python中没有select-case语句。

1
2
3
4
5
6
7
8
9
10
# 1.if reach
if a == 1:
b = 10
elif a == 2:
b = 20
...

# 2.dict reach,better performance
d = {1:10,2:20,...}
b = d[a]

4.直接迭代序列元素

对于序列(str,list,tuple等),直接迭代序列元素比迭代元素索引更快。

1
2
3
4
5
6
7
8
9
a = [1,2,3]

# 1.Iterate elements
for item in a:
print(item)

# 2.Iterate indexes
for i in range(len(a)):
print(a[i])

5.用生成器替换列表表达式

列表表达式将产生一个完整的列表,对大量数据的迭代产生负面影响,但是生成器表达式则没有。

它实际上并没有创建一个列表,而是返回一个生成器,它在需要时产生一个值(延迟),这对内存更友好。

1
2
3
4
5
6
# Calculate the number of non-null characters in file f
# 1.List analysis
l = sum([len(word) for line in f for word in line.split()])

# 2.generator expression
l = sum(len(word) for line in f for word in line.split())

6.先编译再调用

当使用函数eval()exec()来执行代码时,最好调用代码对象(通过compile()函数预先编译成字节码)而不是直接调用str,这样可以避免多次重复编译过程并提高程序的性能。

正则表达式模式匹配是类似的。 在执行比较和匹配之前,最好将正则表达式模式编译为正则表达式对象(通过re.complie()函数)。

7.习惯于模块编程

模块中最高级别的Python语句(无缩进代码)将在导入模块时执行(是否它们真的需要执行呢?)。

因此,您应该尝试将模块的所有功能代码放入函数中(与主程序相关的功能代码也可以放入main()函数,主程序本身调用main()函数)。

测试代码可以写在模块的main()函数中。 将在主程序中检测__name__的值。 如果是__main__(表示模块是直接执行的),则调用main()函数进行测试; 如果它是模块的名称(表示模块被调用),则不会执行测试。