我踩的那些 Python 布尔数组的坑
那天我在做日志埋点数据的去重统计每个用户当天有没有触发过某个事件有就是 True没有就是 False。数据量不大大概几百万行日志我觉得随便写写就行了。上线那天下午运维突然打电话说机器内存炸了。我说不可能啊我代码写得挺简单的啊。运维在电话那头沉默了两秒然后幽幽地来了一句你自己看吧那语气我到现在都记得像极了班主任发现你作业是抄的。我当时写的就是个普普通通的 list装了一堆 True 和 False。打开终端一看进程被 kill 了理由是 OOM。flags[False]*50_000_000# 一个 True/False 在 Python 里是完整对象约 28 字节# 五千万个就是 1.4GB还没开始算就 OOM 了我这才意识到一个 True 在 Python 里可不是一个 bit它是个完整的 Python 对象背后有一整套引用计数和类型信息这些东西一个布尔值吃掉了差不多 28 个字节。几千万个 28 字节堆在一起直接就翻车了。你说气不气我明明只存了个是和否Python 非要给我配一整套户口本。那一刻我脑子里就一句话这波血亏。我甚至怀疑 Python 是不是觉得我存的是个有身份的布尔值得给它上户口、办社保、交公积金。后来我换成了 array以为 stdlib 的东西总归靠谱。写的时候还挺高兴内存确实降下来了几千万条记录也能跑。我当时还跟同事吹牛说你看标准库就是稳一个字节一个布尔这不就解决了嘛。fromarrayimportarray flagsarray(b,[0])*50_000_000# 每个元素只占 1 字节内存确实下来了# 但业务线一扩长度一变它又开始吃紧结果改需求了老板说要扩充到好几个业务线数据量大了一截array 又倒了。我心里窝火得很感觉每个方案都只差那么一口气就像打游戏差最后一刀就能通关结果 boss 狂暴了。这波啊这波是我裂开了。我那天晚上回家路上还在想是不是我写代码的姿势不对要不要去庙里拜拜。然后我想到 numpy。写数据处理嘛迟早得用它的。用了半年没事直到有一次上游来了一个亿的数据直接把进程干掉了。numpy 的 bool_ 虽然是比 list 省多了但一个 bool 也要一个字节一个亿就是一百兆左右再加上副本、临时变量、广播计算实际跑起来内存经常爆表。importnumpyasnp flagsnp.zeros(100_000_000,dtypebool)# bool_ 一个占 1 字节一亿就是 100MB# 加上副本和广播内存直接爆表那种报错框跳出来的时候我就坐在椅子上发呆心想一个亿就炸了后面还有十亿的量等着呢。这感觉就像你刚换了个大点的钱包结果工资还没捂热账单先来了。我当时只想对 numpy 说一句你礼貌吗我甚至能脑补出 numpy 的内心独白你要的是省内存我可没说我不吃内存啊。我这时候有点急了开始翻各种文档。找到 bitarray 的时候觉得看到了光一个 bit 存一个布尔值这才是正解啊。一亿个布尔值才十几兆内存瞬间就安全了。我当时激动得差点在工位上喊出来同事以为我中了彩票。frombitarrayimportbitarray flagsbitarray(1_000_000_000)# 一个 bit 存一个布尔值内存确实省# 但十亿个 bit 搬进 CPU 的那条路成了新的瓶颈我高高兴兴换成 bitarray 跑了两天然后数据量又涨了过了十亿之后它也开始扛不住。不是内存不够而是操作变得很慢。我后来才明白十几兆看着小但数据量大了以后从内存往 CPU 搬数据这件事本身就变成了瓶颈内存占用多就会卡这就是所谓的内存墙普通人直观感受就是电脑风扇狂转、进度条凝固罢了。就像你搬家东西是少了但路就那么宽一趟趟搬反而更慢。这大概就是传说中的路虽近堵车。我那时候盯着风扇狂转的电脑感觉它不是在跑程序是在跟我抗议。也不是没人推荐我用 scipy.sparse。我试了文档写得是真晦涩sparse.csr_matrix 把布尔数据转成稀疏矩阵处理。写起来还行查那个 nonzero 的速度也挺利索。但在我的场景里密度不固定有时候稀疏部分突然变密它就僵在那儿转圈了。fromscipy.sparseimportcsr_matrix flagscsr_matrix((1,100_000_000),dtypebool)# 稀疏矩阵适合数学场景密度一上来就僵住# 函数调用开销大千万次叠加就卡sparse 的初衷是处理数学上的稀疏矩阵跟我的布尔序列批量标记匹配不是一回事函数调一次开销大千万次叠加起来就变成肉眼可见的卡顿。这就像你拿了个专业单反去拍大头贴功能是强大但快门按下去那一下够你喝杯茶了。我只能说这波是杀鸡用牛刀牛刀还卡壳。我甚至怀疑 scipy 是不是觉得我这种用法是在侮辱它。把 scipy.sparse 删掉那天下午我随手在 GitHub 上瞎搜纯粹是碰运气。翻了好几个不相关的项目最后撞上一个叫 bool-hybrid-array 的库星星少得可怜但因为名字里有 hybrid 我就点进去了。我当时想的是反正都这样了看看也不亏。说实话第一眼看到那个 star 数我心里是打鼓的毕竟谁都不想在生产环境里赌一个随时可能没人维护的库。但翻完 README 和源码我反而踏实了它底层就是 numpy 和 array 这两个我天天在用的东西没有自己造轮子没有黑魔法核心逻辑就几百行我甚至能一行行看懂它在干嘛。这种库反而让我放心因为它不依赖什么玄学就是老老实实把两个成熟方案拼在一起出问题我也能自己进去改。看了两眼它的逻辑我就傻了。它居然把数组切成两块一块是密集区用 numpy.ndarray 存因为多数是连续 True 或连续 False这部分操作快另一块是稀疏区用 array.array 存因为是零散的异常值只记录索引就够了。它不是猜它是自动根据内容判断该走哪条路。我拿自己那个快把我逼疯的数据塞进去跑内存从过去的百兆级别直接掉到了十几兆手指点在回车上的瞬间已经返回结果了。那一刻我差点从椅子上跳起来感觉像在垃圾堆里捡到了宝。这波啊这波是真香。我甚至想给这个库的作者发个红包虽然我不认识他。后来我又仔细看了下它的依赖就 numpy 和 array都是 Python 生态里最老牌、最稳的东西它自己只是薄薄一层封装没有引入任何冷门依赖。这意味着就算这个库哪天不更新了只要 numpy 和 Python 还在它就能一直跑我甚至可以直接把它的核心逻辑抄进自己项目里反正就几百行。这种底层全是熟脸的库用起来是真的安心。我后来专门试了一下修改长度的情况。很多方案一开始内存小跑得快但只要长度一改比如追加或删除一段内存立刻就掀翻。list 的扩容策略会预留空间array 也一样numpy 更狠改长度意味着整块重新申请内存一亿规模的数组 resize 一下程序直接僵住。我试过在 numpy 上动态追加数据每次 append 都像在开盲盒不知道哪次就内存错误了。这个方案的好处是它两面都有密集部分用 numpy但那部分长度是不怎么变的稀疏部分用 array长度可变但没有重新申请整块的压力。长度变化时的内存墙在它这儿不算是绝症因为它把变量部分放在了负担最轻的地方。我后来想想这就像搬家的时候把重的东西放固定位置轻的东西随便挪反而最省力。而且它没有搞什么花里胡哨的 C 扩展或者编译步骤pip 装完就能用跟装 numpy 一样省心不会出现那种装个库还要配半天编译环境的糟心事。对我来说一个库稳不稳就看两件事一是底层是不是熟脸二是装起来麻不麻烦这两点它都过关了。我现在回想起那些半夜对着 top 命令发呆的日子就觉得好笑。最开始只是一个 list后来 array、numpy、bitarray、scipy.sparse一个接一个地试每次都是换个场景换个死法。直到翻到一个没几个人 star 的库才把这条路走通。有时候真觉得踩坑这事儿踩得多了坑都认识你了。这大概就是传说中的菜是原罪但菜着菜着也就熟了。我现在看到内存相关的报错第一反应不是慌而是先笑一声然后默默打开 GitHub 开始搜。不过说真的我一开始也担心过这个库会不会哪天就没人管了。毕竟 star 数摆在那儿谁看了都得犹豫一下。后来我实在憋不住直接去 GitHub 上给作者发了封邮件问他这库还维护不维护。结果他回得挺快说只要他没事就不会停止维护有时候忙起来可能几个月没动静但一闲下来就疯狂更新跟打了鸡血似的。我顺手翻了翻版本历史好家伙真不是吹的隔三差五就一个 commit有时候一天好几个那更新频率比我写日报还勤。看到这儿我彻底放心了这哪是没人管的弃坑项目分明是作者拿它当亲儿子在养。而且它底层就依赖 numpy 和 array 这两个 Python 生态里最老牌、最稳的库没有引入任何冷门依赖没有自己造轮子没有黑魔法。这意味着就算哪天它真不更新了只要 numpy 和 Python 还在它就能一直跑。我甚至可以直接把它的核心逻辑抄进自己项目里反正代码就摆在那儿出问题我也能自己进去改。这种底层全是熟脸的库用起来是真的安心比那些动不动就拉一堆依赖、装个库还要配半天编译环境的家伙靠谱多了。

相关新闻

fatal error in launcher:unable to create process using 解决办法

fatal error in launcher:unable to create process using 解决办法

安装python库的时候老是提示:fatal error in launcher:unable to create process using,script目录也添加到了系统变量path中,就是报错。不直接pip安装了,换了命令:python -m pip install 库名称下载源,运行成功。遇到同问题的…

2026/10/27 7:19:55 阅读更多 →
HTML5 Form 表单新特性:减少一半JS校验代码

HTML5 Form 表单新特性:减少一半JS校验代码

HTML5 Form 表单新特性:减少一半JS校验代码 在现代Web开发中,表单验证一直是前端开发者最头疼的工作之一。传统的JavaScript校验往往需要编写大量重复代码来处理输入格式、必填项、错误提示等问题。幸运的是,HTML5引入了一系列强大的表单特性…

2026/10/23 13:48:36 阅读更多 →
Magisk_AsoulOpt终极指南:如何快速优化300+款安卓游戏性能

Magisk_AsoulOpt终极指南:如何快速优化300+款安卓游戏性能

Magisk_AsoulOpt终极指南:如何快速优化300款安卓游戏性能 【免费下载链接】Magisk_AsoulOpt 项目地址: https://gitcode.com/GitHub_Trending/ma/Magisk_AsoulOpt Magisk_AsoulOpt是一款强大的Android游戏线程调整程序,专为骁龙设备优化游戏性能…

2026/10/24 4:19:22 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/27 4:06:49 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/26 4:52:12 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/27 6:20:47 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/27 4:06:50 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 13:21:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →