我给 PHP 数组加了一个键,代价是 25 MB 内存
来源:dev.to — 2026-09-14
📋 概述
作者在重构一段遗留 PHP 代码时发现同一个数组被以完全不同方式使用,于是动手实测 PHP 数组的内存布局。在 PHP 8.4.21 的官方 php:8.4-cli 容器里,一百万个整数的紧凑列表占 16.8 MB;把同样的键值按倒序写入,就变成 41.9 MB——仅仅因为填充顺序不同,内存涨到 2.5 倍。原因是引擎只在键是 0、1、2 这样连续的「packed」列表时才不存储键本身,一旦退化成哈希表,每个元素都要额外保存 bucket 与哈希元数据。文章的核心提醒是:大批量查询结果按行存成关联数组,才是真实的成本大头,而修法比问题本身小得多。
🔑 核心要点
- 同样一百万个整数,正序填充只需 16.8 MB,倒序填充却要 41.9 MB。
- 差异来自引擎的 packed 优化:键是连续递增整数时才不存键本身,否则数组退化成真正的哈希表。
- 把键换成单字符字符串,内存从 16.8 MB 涨到 41.9 MB,也就是「一个键花掉 25 MB」。
- 所有测量都基于 memory_get_usage() 的差值,作者提醒最后两位数字受分配器粒度影响,可当噪声。
- PHP 8.2 改变了其中一个关键数值,作者特意在 8.1.34 上重跑同一份脚本,保留改前改后的对照。
- 真实成本出在查询结果行上:每个 codebase 都把行存成关联数组,而修复方案比问题本身更小。
💡 金句
同一批一百万个整数,我不过是倒着填进去,内存就变成了原来的两倍半。
👍 0
👎 0
← 返回 dev.to 首页