位掩码Bitmap比int或list节省约32倍内存,如1亿用户签到仅需12.5MB;其连续内存布局减少GC压力与缓存失效,且位运算高效;但需手动预分配容量防越界,定位字节用n>>3、位偏移用n&7。

为什么不用 int 直接存状态,而要用位掩码 Bitmap
因为内存开销差 32 倍以上。比如存 1 亿个用户是否签到(只有 0/1),用 Python 的 list[bool] 或 dict 至少占 100MB+;而 Bitmap 只需约 12.5MB:100_000_000 // 8 字节。关键不是“省空间”,而是避免 GC 压力和缓存失效——bytearray 是连续内存块,CPU 缓存友好,set_bit 和 get_bit 都是单条位运算,没有哈希计算或指针跳转。
bytearray 实现 Bitmap 时最常踩的越界坑
Bitmap 不会自动扩容,也不报 IndexError。给定最大 ID 为 n,你必须确保分配的字节数 ≥ (n >> 3) + 1。否则 bitmap[n >> 3] 访问越界,结果不可预测(可能静默写入相邻内存,也可能读到 0)。
- 错误写法:
bitmap = bytearray(100)却调用set_bit(1000)→1000 >> 3 == 125,访问第 125 个字节,但数组只有 100 个字节 - 正确做法:构造时算足容量,例如支持 ID 0~999999,就用
bytearray((999999 >> 3) + 1) - 调试技巧:在
set_bit里加if n >> 3 >= len(bitmap): raise ValueError(f"ID {n} exceeds bitmap capacity")
set_bit 和 get_bit 的位运算细节与兼容性问题
核心就是两步:定位字节 + 定位位。Python 中推荐用位移替代除法取模,既快又避开了负数取模陷阱(比如 -1 % 8 == 7,但 ID 不该为负)。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
-
set_bit(n):先算字节索引n >> 3,再算位偏移n & 7,然后执行bitmap[n >> 3] |= (1 -
get_bit(n):同上得字节和位偏移,再用(bitmap[n >> 3] >> (n & 7)) & 1提取单 bit - 注意:
1 在旧版 CPython 的 <code>array.array('B')上可能触发DeprecationWarning,统一用bytearray更稳
什么时候该换用 bitarray 库而不是手写
手写适合简单、固定场景(如签到、日活统计);一旦需要切片、批量操作、序列化或跨进程共享,bitarray 就值得引入。它底层用 C 实现,支持 bitarray[100:200] 切片、.to01() 转字符串、.frombytes() 快速加载等。
立即学习“Python免费学习笔记(深入)”;
- 安装:
pip install bitarray - 等价操作:
b = bitarray(1000000); b[5] = True; b[5],语义清晰,不用手动算偏移 - 但注意:它不兼容 pickle 默认协议(需用
protocol=4或更高),且不能直接 mmap 到文件——如果要持久化大 Bitmap,还是得回到bytearray+mmap组合

















