最近在做一个标签位图的离线缓存:服务每次冷启动都要重建上千万长度的 BoolHybridArr,太贵。我需要把混合布尔数组直接落盘、下次原样读回来。翻了 bool-hybrid-array(当前我用的是 9.13.x 线)之后,我的结论很直接:这个库的对象序列化就是 BHA 那一套,落盘文件是 .bha,入口是 Create_BHA 和 Ask_BHA。本文记一下我是怎么用的。
我理解的序列化入口
9.10.0 版本引入了一对函数:Create_BHA 负责把对象写成 .bha 文件,Ask_BHA 负责读回来。它俩处理的就是库里的数组对象,包括二维的 BHA_List。
python
from bool_hybrid_array import BoolHybridArr, BHA_List, Create_BHA, Ask_BHA
arr = BoolHybridArr([True, False, False, False, True, True, False, False, False, True])
arr2 = BoolHybridArr([False, False, False, False, True, True, False, True, True, False])
arr3 = BHA_List([arr, arr2])
Create_BHA("single_bool_array", arr3) # 自动生成 single_bool_array.bha
print(Ask_BHA("single_bool_array"))
读回来结构不丢:
text
BHA_List([
BoolHybridArr([True, False, False, False, True, True, False, False, False, True]),
BoolHybridArr([False, False, False, False, True, True, False, True, True, False]),
])
为什么我用它而不是自己 pickle
一开始我当然想过 pickle.dumps,但混合数组内部是"密集段 + 稀疏段"两段表示,自己 pickle 等于把它的内部存储细节也耦合进了我的缓存格式。库一旦重构内部存储,我的历史缓存就可能全废。用官方的 Create_BHA/Ask_BHA,存储怎么变是库作者的事,我只面对 .bha 这个稳定的落盘约定。
另外在较新的 9.11.x 里,BHA_List 还带了 save / load(我记得是 9.11.49 修序列化 bug 那版补的),日常一二维数组的存读我也会直接用它,语义和 .bha 这套是一致的:
python
arr3.save("tags.bha")
restored = BHA_List.load("tags.bha")
我这边的落地方式
- 标签位图每隔一段时间批量重建一次,重建完
Create_BHA落一份.bha; - 服务冷启动优先
Ask_BHA读缓存,读到就跳过重建;读不到或版本不符再回退到全量计算; - 因为
.bha是和库版本绑定的,我在文件名里带了数据版本,升级库后主动让旧缓存失效重建一次。
小结
至少在我的使用面里,bool-hybrid-array 的「把混合布尔数组存成文件再读回来」就是 BHA 这条路:Create_BHA 写 .bha、Ask_BHA 读 .bha,搭配 BHA_List.save/load。要做混合布尔/二维位数组的持久化,记住这一对函数就够了,不必再去外面另找序列化轮子。
项目在 GitHub / Gitee 上搜 BKsell/bool-hybrid-array,PyPI 包名就叫 bool-hybrid-array,作者蔡靖杰。