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; ?>
】
相关推荐
- c++怎么实现大文件的分块读写_c++ 文件指针s
- c++如何使用std::bind绑定函数参数_c+
- Mac系统更新下载慢或失败怎么办_解决macOS升
- Windows10怎么用“讲述人”读屏辅助 Win
- php修改数据怎么改富文本_update更新htm
- Python 中将 ISO 8601 时间戳转换为
- Linux如何挂载新硬盘_Linux磁盘分区格式化
- Mac怎么设置鼠标滚动速度_Mac鼠标设置详细参数
- 如何使用Golang实现错误包装与传递_Golan
- 使用类变量定义字符串常量时的类型安全最佳实践
- php订单日志怎么按状态筛选_php筛选不同状态订
- 作用域操作符会影响性能吗_php静态调用性能分析【
- 如何提升Golang JSON序列化性能_Gola
- Windows7怎么找回经典开始菜单_Window
- Win11任务栏颜色怎么改_Win11自定义任务栏
- Ajax提交表单PHP怎么接收_处理Ajax发送的
- 如何使用Golang编写单元测试_创建Test函数
- 如何在Golang中配置代码格式化工具_使用gof
- c# 在ASP.NET Core中管理和取消后台任
- Win11怎么设置闹钟_Windows 11时钟应
- 如何在Golang中使用container/hea
- MAC如何安装Git版本控制工具_MAC开发环境配
- LINUX如何删除用户和用户组_Linux use
- Win11色盲模式怎么开_Win11屏幕颜色滤镜设
- 如何使用Golang处理网络超时错误_Golang
- Win11如何设置电源计划_Win11电源计划优化
- 如何高效识别并拦截拼接式恶意域名 spam
- PHP主流架构怎么处理表单验证_规则与自定义【技巧
- 如何解决Windows字体显示模糊的问题?(Cle
- mac怎么打开终端_MAC终端Terminal使用
- php报错怎么查看_定位PHP致命错误与警告的方法
- 如何使用Golang benchmark测量函数延
- c# 如何用c#实现一个支持优先级的任务队列
- Win11如何设置系统声音_Win11系统声音调整
- Windows如何使用注册表查找和删除项?(reg
- php中$this和::能混用吗_对象与静态作用域
- php8.4匿名类怎么用_php8.4匿名类创建与
- 如何使用Golang匿名函数_快速定义临时函数逻辑
- 如何在Golang中引入测试模块_Golang测试
- Windows10如何删除Windows.old_
- Win11怎么更改鼠标指针_Windows 11自
- 如何自定义Windows终端的默认配置文件?(Po
- c++ namespace命名空间用法_c++避免
- 如何使用Golang实现RPC序列化与反序列化_G
- 如何优化Golang内存分配与GC调度_Golan
- Win11怎么关闭搜索历史_Win11清除任务栏搜
- Win11蓝牙开关不见了怎么办_Win11蓝牙驱动
- Win11怎么查看激活状态_查询Windows 1
- Windows10怎么备份注册表_Windows1
- c++怎么用jemalloc c++替换默认内存分


QQ客服