全局变量在循环中变慢,因每次访问需查全局命名空间(字典查找),比局部变量慢2–3倍;应将math.sqrt等绑定为局部变量或用from math import sqrt优化。

为什么全局变量在循环里变慢
Python 每次访问 math.sqrt、os.path.join 或 len() 这类全局名,都要查一次全局命名空间——本质是字典查找,比局部变量慢 2–3 倍。这在普通逻辑里不明显,但一旦进百万级循环或高频 I/O 回调,就成了瓶颈。
把模块函数和方法绑定成局部变量
这不是“导入优化”,而是绕过属性链查找的硬核提速手段。
- 错:
for x in data: result.append(math.sqrt(x))—— 每次都走math→sqrt两层查找 - 对:
sqrt = math.sqrt; apd = result.append; for x in data: apd(sqrt(x))—— 全部是纯局部名引用 - 更干净写法:
from math import sqrt放在函数开头(不是模块顶层),避免污染全局命名空间,也防止被 monkey patch 影响
别在循环条件里反复调用 len() 或 range()
len() 虽快,但仍是函数调用;range(len(items)) 更糟:每次迭代都查 range 和 len 两个全局名。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 错:
for i in range(len(items)): - 对:
n = len(items); for i in range(n): - 更推荐:
for item in items:—— 根本不碰索引就别碰len - 注意:
while i 同样危险,应提前提取 <code>limit = len(items)
哪些不该提、哪些必须提
局部化不是银弹,盲目替换反而让逻辑难读、难维护。
立即学习“Python免费学习笔记(深入)”;
- 该提:
re.compile(r'...')、math.pi、稳定不变的模块函数(如json.loads) - 不该提:
time.time()(值随时变)、random.random()(状态依赖)、被外部 patch 过的函数(比如某些 ORM 的 query 方法) - 特别注意:
__slots__对实例属性访问提速有效,但只在大量创建同类对象 + 频繁读写属性时才值得加;加了就禁用__dict__,别在需要动态属性的类上硬套
真正卡住性能的,从来不是某一行代码多花了纳秒,而是同一处逻辑被重复执行十万次还带着三重查找。盯住你 profile 出来的 top 3 hotspot,只在那里动刀子。

















