Python技术迷

如何优化Python代码的性能?

说真的,别一上来就想着加啥多线程多进程,先看看你代码到底慢哪了。你光凭感觉搞优化,那不是“玄学调优”吗?我之前也犯过类似错误,手写一堆for循环,跑半天,最后发现是I/O操作拖的后腿,白折腾一晚上。你用time模块随便包一层:

import time

start = time.time()
# 你的代码段
end = time.time()
print('耗时:', end - start)

就这样,先知道自己慢在哪,别着急往多核分布式那方向冲。要是业务逻辑本身就写得臃肿,优化个寂寞。

别再手搓循环了,用内置函数

我特别受不了,有些人动不动就写好几层for循环,map、filter、list comprehension不用白不用啊!前几天在地铁上跟人扯淡,他说自己的数据处理慢得一批,我一看,原来是写了个三层嵌套的循环,真服气。你看这样:

# 慢得要死的传统写法
result = []
for i in range(1000000):
    result.append(i * 2)

# 优雅又快的写法
result = [i * 2for i in range(1000000)]

不信你测一下,两者能差一倍以上。map、filter这些底层都是C写的,比你人肉for快多了。

少用全局变量、尽量用局部变量

这个真是血泪教训,我印象特别深。前两天组内CodeReview,有人写个函数里面全是global,调用堆全局变量,结果函数调用一多,性能直线下降。Python函数查找变量,先查局部,再查全局,局部快多了。所以你变量能放在局部,就别放全局。

尽量用生成器

这个也是,尤其是处理大数据量的时候,yield用起来是真的香。你要是还老想着用个list先全存下来,那内存分分钟爆掉。举个例子:

defread_big_file(file_path):
with open(file_path) as f:
for line in f:
yield line

for line in read_big_file('log.txt'):
# 处理每一行
pass

这样一行行来,内存用多少拿多少,贼省事。之前有次日志文件二十几个G,要不是用生成器,我电脑直接卡死。

真的慢到忍不了,再考虑多进程多线程

你真要用并发?先看清楚自己CPU是不是能带得动,I/O型的任务用多线程,CPU密集型任务多进程。Python有个GIL,单线程CPU任务根本提速不了。上次我帮小王改个爬虫,他写了多线程结果没提速,我说你用多进程,才发现刷刷往上涨。随便来个例子:

from concurrent.futures import ProcessPoolExecutor

defcpu_task(x):
return x ** 2

with ProcessPoolExecutor() as executor:
    results = list(executor.map(cpu_task, range(10)))
print(results)

不过,多进程用多了,内存也会飞,别瞎加。

第三方库一定要用对

老实说,NumPy/Pandas这些库,用得熟,才是真的快。你还在for循环做矩阵运算,人家用NumPy一行就能干完还巨快。比如:

import numpy as np

a = np.arange(1000000)
b = a * 2

和你用for循环效率不是一个量级。再说Pandas,处理表格数据直接vectorized操作,效率刷刷的。

内存问题也别忽视

有时候你觉得自己优化得够快了,结果一堆对象没释放,内存耗完直接崩溃。要是用完变量记得del一下,或者局部作用域外面别留垃圾。大对象、临时变量啥的,用完早点丢,别拖累你后面代码。

cProfile先撸一遍

真要调优,上来先整cProfile看哪里最慢。python -m cProfile your_script.py,一跑全知道哪里拉胯。我之前有次查一个接口慢到要死,cProfile一看,是个正则写得太复杂,后来一改,提速80%。

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领