Python 性能优化思路:局部变量、循环优化与生成器
技术百科
舞夢輝影
发布时间:2026-01-27
浏览: 次 局部变量比全局变量快,因Python用LOAD_FAST直接索引栈帧,而LOAD_GLOBAL需遍历模块字典;循环中应避免字符串累加、重复类型检查和冗余索引;生成器适合大数据流式处理,小数据全量消费时反增开销。
为什么局部变量比全局变量快?
Python 访问局部变量走的是 LOAD_FAST 指令,而全局变量是 LOAD_GLOBAL,后者要遍历模块字典、可能触发属性查找,慢 2–5 倍。这不是“微优化”,在高频循环里会明显拖累。
实操建议:
- 把频繁使用的全局对象(如
math.sin、re.compile()的结果)提前赋值给函数内变量 - 避免在循环中重复写
import os或from json import loads—— 导入本身不耗时,但引用时若没缓存,会多一次命名空间查找 - 用
dis.dis()看字节码验证:局部变量对应LOAD_FAST,全局/内置名是LOAD_GLOBAL或LOAD_BUIL
TIN
for 循环里哪些操作最伤性能?
真正拖慢循环的往往不是迭代本身,而是每次迭代中隐式开销大的操作。比如反复调用方法、拼接字符串、做类型检查。
常见错误现象:
-
result += item在循环中拼接字符串 → 触发多次内存分配和拷贝(O(n²)) -
if isinstance(obj, list): ...放在内层循环 → 每次都走类型系统路径 -
for i in range(len(data)):再用data[i]→ 多一次索引查找 +len()调用(虽有优化,但不如直接迭代)
改法示例:
# 慢
s = ""
for x in items:
s += str(x)
快
s = "".join(str(x) for x in items)
生成器什么时候该用、什么时候不该用?
生成器节省内存,但未必省时间。它把计算延迟到取值时,如果所有值最终都要被消费,且中间没有过滤/截断,那生成器反而增加函数调用开销(yield 是协程调度点)。
使用场景判断:
- 适合:数据源巨大、只需前 N 项(
itertools.islice(gen, 100))、或需流式处理(边读文件边解析) - 不适合:小列表(gen[5] 不支持)、或后续要多次遍历(生成器只能用一次)
- 注意:
list(gen)会立刻耗尽生成器并分配全部内存,等于白用
一个易忽略点:yield from 在嵌套生成器时比手动 for...yield 快约 10%——Cython 编译后差距更大。
profile 之前别猜,但 profile 之后别只看总时间
用 cProfile.run('foo()') 或 line_profiler 才能定位真实瓶颈。很多人优化了 math.sqrt() 调用,却没发现 90% 时间花在 json.loads() 的字符串解码上。
关键提醒:
- 局部变量优化只有在函数被高频调用(如每秒数千次)时才值得单独提取
- 生成器的 yield 开销约 50–100ns,单次不明显,但嵌套三层+每秒百万次就不可忽视
-
for x in iterable的底层是iter()+next(),如果iterable是自定义类,__iter__和__next__实现质量直接影响性能
# 的是
# 放在
# 大数据
# python
# 都要
# 迭代
# 性能优化
# 什么时候
# js
# json
# 循环
# 对象
# if
# 字节
# 字符串
# 为什么
# 栈
# 命名空间
# len
# 遍历
# 流式
# for
# 该用
# 局部变量
# 全局变量
# math
# 量比
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么更改鼠标指针_Windows 11自
- 微信短链接怎么还原php_用浏览器开发者工具抓包获
- 如何减少Golang内存碎片化_Golang内存分
- Windows10怎么用“讲述人”读屏辅助 Win
- 如何使用Golang实现错误包装与传递_Golan
- c++ stringstream用法详解_c++字
- Win11资源管理器卡顿怎么办 Win11文件资源
- 如何在 Django 中安全修改用户密码而不使会话
- Win11怎么关闭自动修复_跳过Win11开机自动
- Mac如何查看电池健康百分比_Mac系统信息电源检
- Win11怎么关闭触控板_Win11笔记本禁用触摸
- 如何在 Go 中判断变量是否为函数类型
- Windows10怎么查看系统激活状态_Windo
- c++的mutex和lock_guard如何使用
- 如何自定义Windows终端的默认配置文件?(Po
- Win11如何设置文件权限 Win11 NTFS文
- Django密码修改后会话失效的解决方案
- Win10如何更改电脑休眠时间_Windows10
- C#如何序列化对象为XML XmlSerializ
- C++如何解析JSON数据?(nlohmann/j
- C++如何将C风格字符串(char*)转换为std
- Go 中 defer 语句在 goroutine
- 微信企业付款回调PHP怎么接收_处理企业付款异步通
- Win11如何设置ipv6 Win11开启IPv6
- LINUX怎么进行文本内容搜索_Linux gre
- 如何在 ACF 中正确更新嵌套多层的 Group
- 如何开启Windows的远程服务器管理工具(RSA
- C++中的std::shared_from_thi
- Linux如何安装JDK11_Linux环境变量配
- Win11怎么关闭通知消息_屏蔽Windows 1
- Python 模块的 __name__ 属性如何由
- Python爬虫项目实战教程_Scrapy抓取与存
- php查询数据怎么导出csv_查询结果转csv文件
- php485在macos下怎么配置_php485
- Go 语言标准库为何不提供泛型切片的 Contai
- 如何使用Golang优化模块引入路径_Golang
- 如何在 Go 中创建包含 map 的 slice(
- Windows如何使用注册表查找和删除项?(reg
- PHP cURL GET请求:正确设置认证与自定义
- Win11怎么清理C盘系统日志_Win11清理系统
- Python深度学习实战教程_神经网络模型构建与训
- 如何使用 Selenium 正确获取篮球参考网站球
- MAC怎么在照片中添加水印_MAC自带编辑工具文字
- c++怎么用jemalloc c++替换默认内存分
- Win10如何更改任务栏高度_Windows10解
- VSC怎样用终端运行PHP_命令行执行脚本的步骤【
- Win11如何设置自动关机 Win11定时关机命令
- Python安全爬虫设计_IP代理池与验证码识别策
- Windows10如何更改桌面图标间距_Win10
- Windows10如何彻底关闭自动更新_Win10


QQ客服