别再瞎猜瓶颈在哪了
性能优化第一步,永远是精准定位。
cProfile 是你的瑞士军刀。一行命令,函数耗时一目了然。
python -m cProfile -s cumulative your_script.py
看不懂报告? 关注 cumtime 列,它告诉你哪个函数是真正的“时间黑洞”。
内存泄漏?别让程序变成内存怪兽
对象越创越多,内存却不见回收?
用 memory-profiler 给你的代码做个体检。
from memory_profiler import profile
@profile
defmemory_hog():
big_list = [i for i in range(1000000)]
return big_list
运行 mprof run your_script.py,再 mprof plot,一张图看清内存走势,是不是很酷?📈
对象太胖?给它们集体瘦身!
每个Python对象都带着“行李”(__dict__)。
百万级对象?用 __slots__ 直接砍掉50%内存!
classFatClass:
def__init__(self, x, y):
self.x = x
self.y = y
classSlimClass:
__slots__ = ['x', 'y'] # 👈 就这行!
def__init__(self, x, y):
self.x = x
self.y = y
实测:创建一百万个实例,SlimClass 能省下几百MB!
CPU密集型任务?GIL不是你的终点
别被GIL吓住,多进程才是王道。
multiprocessing 让你轻松榨干所有CPU核心。
from multiprocessing import Pool
defcpu_bound_task(n):
return sum(i * i for i in range(n))
if __name__ == '__main__':
with Pool() as pool:
results = pool.map(cpu_bound_task, [1000000] * 4)
四核变四倍速,就是这么简单粗暴。
别再一次性加载整个文件了
处理大文件还用 readlines()?内存分分钟爆炸。
生成器(Generator)是你的救星,懒加载,省内存。
# Bad
with open('huge_file.txt') as f:
lines = f.readlines() # 💥
# Good
defread_line_by_line(filename):
with open(filename) as f:
for line in f:
yield line.strip()
for line in read_line_by_line('huge_file.txt'):
process(line) # 内存占用稳如老狗
用对数据结构,速度翻倍不是梦
list 查找慢?试试 set 或 dict。
O(n) 和 O(1) 的差距,大数据下就是天壤之别。
# 检查一个元素是否在百万数据中
big_list = list(range(1000000))
big_set = set(range(1000000))
# 超慢
if999999in big_list: ...
# 飞快
if999999in big_set: ...
选对工具,事半功倍,这是永恒的真理。
最后一点忠告:先测量,再优化
别凭感觉瞎改代码。
99%的性能问题都集中在那1%的代码里。
用 py-spy 这种采样分析器,甚至不用改代码就能在生产环境抓出瓶颈。
pip install py-spy
py-spy top --pid 12345 # 实时监控进程12345
记住:Premature optimization is the root of all evil.
(过早的优化是万恶之源。)