Python性能优化需权衡解释器行为与运行时约束:用timeit测真实瓶颈;append()比+=快因直接C层操作,但+=更原子;查内存用asizeof或psutil而非getsizeof;lru_cache仅适用于纯函数、可哈希参数、高复用率场景。

Python性能优化不是靠堆砌技巧,而是理解解释器行为、内存模型和运行时约束后做出的权衡。第548讲这个编号没有实际技术含义,真正关键的是:你是否在用 timeit 测量真实瓶颈,还是只在优化根本没被调用的函数?
为什么 list.append() 比 list += [item] 快,但 += 在循环外可能更安全?
因为 list.append() 是就地修改,C 层直接操作内部数组;而 list += [item] 触发序列协议,先构造单元素列表再调用 extend(),多一次对象创建和类型检查。
- 高频小数据追加(如日志收集)——无条件用
append() - 需要原子性或可能被多线程/协程中断时——
+=或extend()更易推理,因为它们是单个字节码指令(INPLACE_ADD),而append()调用本身跨字节码 - 如果
item是生成器或大序列,extend()比反复append()少做多次内存重分配
sys.getsizeof() 不能反映真实内存压力,该看什么?
sys.getsizeof() 只返回对象自身占用的内存,不包含其所引用对象(比如 list 里的元素、dict 的 key/value)。对复合结构几乎无效。
- 查真实内存开销用
pympler.asizeof.asizeof(obj),它递归计算引用链 - 观察进程级内存增长用
psutil.Process().memory_info().rss,配合稳定输入反复运行 - 怀疑内存泄漏时,用
gc.get_objects()按类型统计实例数,重点关注自定义类和闭包
用 functools.lru_cache() 前必须确认这三件事
缓存不是银弹,用错反而拖慢程序。它只适合:纯函数、参数可哈希、结果复用率高。
立即学习“Python免费学习笔记(深入)”;
- 参数含
list、dict、set或自定义不可哈希对象 → 直接抛TypeError - 函数有副作用(如写文件、改全局状态)→ 缓存会跳过执行,逻辑崩溃
- 缓存键爆炸(如传入时间戳、UUID)→
maxsize=None会导致无限增长,OOM 风险比不缓存还高
from functools import lru_cache@lru_cache(maxsize=128) def fib(n): return n if n < 2 else fib(n-1) + fib(n-2)
✅ 安全:int 可哈希,无副作用
❌ 危险:若改成 fib(n, memo={}),memo 字典不可哈希,装饰器失效
最常被忽略的一点:CPython 的 GIL 不会因缓存自动释放,CPU 密集型函数即使加了 @lru_cache,仍阻塞其他线程。真要并发提速,得结合 multiprocessing 或提前把计算卸载到 C 扩展里。











