写了这么多年Python代码,经常看到有小伙伴吐槽Python运行慢。其实只要掌握一些优化技巧,Python代码的性能完全可以得到质的提升。我整理了20个实用的Python性能优化技巧,这些都是我在实际项目中常用的,保证好使。
处理大数据时,用生成器可以显著降低内存占用。生成器逐个产生数据,不会一次性加载所有数据到内存。
# 糟糕的写法
numbers = [x * x for x in range(1000000)]
# 推荐的写法
numbers = (x * x for x in range(1000000))
⚠️ 小贴士:
生成器表达式用圆括号,列表推导式用方括号
生成器只能遍历一次,需要多次使用要重新生成
特别适合处理大文件和大量数据的场景
Python内置函数都是经过优化的C代码实现,性能比自己写的纯Python代码要好得多。
# 性能差
def my_sum(lst):
total = 0
for i in lst:
total += i
return total
# 性能好
total = sum(lst)
选对数据结构能带来显著的性能提升:
# 查找操作频繁用集合
numbers = set([1, 2, 3, 4, 5])
# O(1)复杂度
if 3 in numbers:
pass
# 键值对操作用字典
cache = {}
# 快速查找和更新
cache['key'] = 'value'
# 很慢,每次都创建新字符串
s = ''
for i in range(1000):
s += str(i)
# 快多了,用join一次性拼接
s = ''.join(str(i) for i in range(1000))
⚠️ 小贴士:
用加号拼接字符串时间复杂度是O(n²)
join()方法的复杂度是O(n)
频繁拼接建议用io.StringIO
# 慢
import math
def calc_distance(points):
return math.sqrt((points[1][0] - points[0][0])**2 +
(points[1][1] - points[0][1])**2)
# 快
from math import sqrt
def calc_distance(points):
x1, y1 = points[0]
x2, y2 = points[1]
return sqrt((x2-x1)**2 + (y2-y1)**2)
# 糟糕的写法
def process_data(items):
result = []
for i in range(len(items)):
temp = [] # 每次循环都创建新列表
temp.append(items[i])
result.extend(temp)
# 优化后
def process_data(items):
result = []
temp = [] # 在循环外创建
for i in range(len(items)):
temp.clear() # 重用已有列表
temp.append(items[i])
result.extend(temp)
# 纯Python计算慢
def matrix_multiply(a, b):
result = [[0]*len(b[0]) for _ in range(len(a))]
for i in range(len(a)):
for j in range(len(b[0])):
for k in range(len(b)):
result[i][j] += a[i][k] * b[k][j]
return result
# 用NumPy秒级完成
import numpy as np
result = np.dot(a, b)
# 调用开销大
def get_square(x):
return x * x
squares = [get_square(i) for i in range(1000)]
# 内联计算更快
squares = [i * i for i in range(1000)]
写到这我发现篇幅已经不少了,剩下的12个技巧下次再和大家分享。记住啊,代码优化不是为了优化而优化,性能和可读性要权衡。代码写得对不对,性能测试才知道。经常用 性能分析工具 来找出真正的瓶颈,避免过早优化。