做Python开发的同学一定都遇到过内存优化的问题,尤其是用numpy做大数据处理、机器学习特征工程的时候,布尔数组占的内存经常超出预期。今天这篇Python内存优化实战教程,就教大家怎么把numpy布尔数组从95MB压缩到10MB,性能还能提升30%,看完直接就能用到项目里。
## 一、为什么numpy布尔数组这么占内存?
很多人做numpy性能优化的时候都会忽略布尔值的内存占用:
– numpy.bool_每个值占1字节,看起来很小,但是1亿个布尔值就要占95.4MB
– 如果是10亿个用户标签、特征标记,用numpy存就要近1GB内存,服务器很容易OOM
– 普通的bitarray虽然1bit存一个值,但是随机访问性能差,连续相同值的时候也不压缩,内存还是有浪费
我们线上做推荐系统特征工程的时候,一开始用numpy存10亿个用户布尔特征,内存占了近10GB,服务启动要10秒,做了很多numpy性能优化都没解决根本问题,最后自己实现了一个混合布尔数组才解决。
## 二、Python内存优化最优方案:动态规划混合存储
纯位图和纯RLE都有缺点,最优的Python内存优化方案是用动态规划算法自动混合存储:
1. 连续相同值的区域:自动用RLE行程编码压缩,连续10000个True只需要存两个数,内存几乎为0
2. 随机分布的区域:自动用位图存储,1bit一个值,没有额外开销
3. DP算法O(n)时间计算全局最优分割点,自动平衡压缩率和访问性能,不需要手动配置
## 三、开源实现:bool-hybrid-array
我们把这个Python内存优化方案做成了开源库bool-hybrid-array,核心用Cython -O3编译,把numpy性能优化做到了极致:
### 性能对比(1亿个混合分布布尔值,Python 3.12 / i7-12700K)
| 指标 | Python list | numpy.bool_ | bitarray | BoolHybridArray |
|———————|————-|————-|———-|—————–|
| 1亿值内存占用 | ~812MB | ~95.4MB | ~12.5MB | **~9.7MB** |
| 随机读QPS | 12.6M/s | 29.1M/s | 8.7M/s | **39.2M/s** |
| 顺序写QPS | 8.3M/s | 15.2M/s | 4.1M/s | **30.8M/s** |
| 1亿值序列化到文件 | 12.8s | 2.1s | 1.7s | **0.19s** |
做numpy性能优化之后,内存只有原来的1/10,随机读性能比numpy还快35%,序列化速度快11倍,服务冷启动直接从10秒降到0.2秒。
### 使用方法
100%兼容Python list和numpy常用API,零学习成本,直接替换就行:
```python
# 安装
pip install bool-hybrid-array
# 使用
from bool_hybrid_array import BoolHybridArray
# 和list用法完全一样
arr = BoolHybridArray()
arr.append(True)
arr.append(False)
print(arr[0])
print(arr[1:3])
print(len(arr))
```
其他优化点:
– 内存池预分配,减少系统调用开销
– 热点路径无GIL,支持多线程,numpy性能优化多线程场景也能用
– ctypes直接调用系统IO,绕过Python层,序列化速度和C++差不多
– MIT协议,完全开源免费可商用
## 四、适用场景
这个Python内存优化方案特别适合这些场景:
1. **机器学习/特征工程**:存用户标签、one-hot特征、标记位,内存直接省90%
2. **位图索引/布隆过滤器**:比普通位图内存更小,访问更快
3. **大数据ETL**:存海量数据的去重标记、状态位,几亿数据也不爆内存
4. **高性能在线服务**:做特征缓存,序列化快,服务启动速度提升5-10倍
我们线上用了这个numpy性能优化方案之后,10亿用户特征从10GB内存降到了1GB不到,效果非常明显。
## 五、项目地址
开源地址:https://gitee.com/BKsell/bool-hybrid-array
直接pip安装就能用,代码全部开源,做Python内存优化、numpy性能优化的同学可以试试,觉得好用的话点个star支持一下~
这篇教程从问题到解决方案一步步讲清楚,代码直接复制就能用,建议收藏,下次做Python内存优化的时候直接套方案。
网硕互联帮助中心





评论前必须登录!
注册