性能优化应优先于代码优雅:高频循环用预分配数组和显式for,数值计算用array/numpy,IO密集用异步或mmap,日志批量刷盘,轻量数据用tuple/NamedTuple,字符串拼接用join,查找用set,计数用Counter,数值计算向量化。

当代码运行明显变慢、内存占用飙升,或在关键路径上成为瓶颈时,就该放下“优雅”去换性能。
高频循环里别写 Pythonic 一行式
像 [x * 2 for x in data if x > 0] 看着干净,但如果 data 是百万级列表且在实时处理中反复执行,生成新列表+遍历两次的开销会很实在。这时候拆成预分配数组 + 显式 for 循环,配合 break 或提前返回,往往快 2–5 倍。
- 用
array.array或numpy.ndarray替代普通 list 存数值数据 - 避免在循环内做重复计算(比如把
len(seq)提到外面) - 用
itertools.islice或生成器切片代替list[start:end]复制
IO 密集场景下,“简洁”的同步写法可能拖垮吞吐
比如用 requests.get(url) 串行抓 100 个网页,代码只有 3 行,但耗时可能是并行请求的 80 倍。此时“优雅”的阻塞调用反而成了性能毒药。
- 改用
aiohttp+async/await并发请求 - 文件读写量大时,用
open(..., buffering=8192)调整缓冲区,或直接 mmap - 日志写入频繁?关掉每条都 flush 的默认行为,用队列+单独线程批量刷盘
对象模型太重?该用元组/命名元组就别硬套类
一个只存 3 个字段、生命周期短、不需方法的配置项,用 dataclass 或普通 class 创建几千次,比用 tuple 或 namedtuple 多占 30%–50% 内存,初始化也慢一截。
立即学习“Python免费学习笔记(深入)”;
- 纯数据容器优先考虑
typing.NamedTuple或collections.namedtuple - 不需要继承和动态属性时,加
__slots__ = ('a', 'b', 'c')节省内存 - 临时中间结果尽量用生成器表达式
(x*2 for x in data),而非列表推导
第三方库已有高效实现,别自己“优雅”重造轮子
比如想“优雅地”用 functools.reduce(operator.add, strings) 拼接长字符串——这其实是 O(n²) 的灾难;而 ''.join(strings) 是 C 层优化过的 O(n)。
- 字符串拼接一律用
join - 查找存在性:用
item in set而非item in list - 计数统计优先
collections.Counter,别手写字典累加 - 数值计算能用
numpy向量化就别写 for,哪怕多引入一行 import
性能不是永远压倒可读性,但在明确可观测的瓶颈处,“够快”就是最务实的优雅。











