一个PHP数组应该有多大的分析


Posted in PHP onJuly 30, 2009

虽然通常在PHP中进行大量数组运算从一定程度上反应程序设计上可能存在问题,但是粗略的估计数组占用的内存是很有必要的。
首先感觉一下1000个元素的整数数组占有的内存:

echo memory_get_usage() . “\n”; 
$a = Array(); 
for ($i=0; $i<1000; $i++) { 
$a[$i] = $i + $i; 
} 
echo memory_get_usage() . “\n”; 
for ($i=1000; $i<2000; $i++) { 
$a[$i] = $i + $i; 
} 
echo memory_get_usage() . “\n”;

输出是:
58176
162956
267088
大 约可以知道 1000 个元素的整数数组需要占用 100k 内存,平均每个元素占用 100 个字节。而纯 C 中整体只需要 4k。memory_get_usage() 返回的结果并不是全是被数组占用了,还要包括一些 PHP 运行本身分配的一些结构,可能用内置函数生成的数组更接近真实的空间:
echo “init mem: ” . memory_get_usage() . “\n”; 
$a = array_fill(0, 10000, 1); 
echo “10k elements: ” . memory_get_usage() . “, system: ” . memory_get_usage(true) . “\n”; 
$b = array_fill(0, 10000, 1); 
echo “10k elements: ” . memory_get_usage() . “, system: ” . memory_get_usage(true) . “\n”;

得到:
init mem: 58468
10k elements: 724696, system: 786432
10k elements: 1390464, system: 1572864
从这个结果来看似乎一个数组元素大约只占用了 60 个左右的字节。再看看数组的C结构,PHP 中的数组变量,首先需要一个 zval 结构:
struct _zval_struct { 
zvalue_value value; 
zend_uint refcount__gc; 
zend_uchar type; 
zend_uchar is_ref__gc; 
};

zvalue_value 是一个union:
typedef union _zvalue_value { 
long lval; 
double dval; 
struct { 
char *val; 
int len; 
} str; 
HashTable *ht; 
zend_object_value obj; 
} zvalue_value;

通常 zval 结构需要 8+6=14 个字节,PHP中每个变量都有对应的 zval,但是数组,字符串和对象还需要另外的存储结构,而数组则是一个 HashTable :
typedef struct _hashtable { 
uint nTableSize; 
uint nTableMask; 
uint nNumOfElements; 
ulong nNextFreeElement; 
Bucket *pInternalPointer; 
Bucket *pListHead; 
Bucket *pListTail; 
Bucket **arBuckets; 
dtor_func_t pDestructor; 
zend_bool persistent; 
unsigned char nApplyCount; 
zend_bool bApplyProtection; 
} HashTable;

HashTable 结构需要 40 个字节,每个数组元素存储在 Bucket 结构中:
typedef struct bucket { 
ulong h; 
uint nKeyLength; 
void *pData; 
void *pDataPtr; 
struct bucket *pListNext; 
struct bucket *pListLast; 
struct bucket *pNext; 
struct bucket *pLast; 
char arKey[1]; 
} Bucket;

Bucket 结构需要 36 个字节,键长超过四个字节的部分附加在 Bucket 后面,而元素值很可能是一个 zval 结构,另外每个数组会分配一个由 arBuckets 指向的 Bucket 指针数组, 虽然不能说每增加一个元素就需要一个指针,但是实际情况可能更糟。这么算来一个数组元素就会占用 54 个字节,与上面的估算相差不远。
一个空数组至少会占用 14(zval) + 40(HashTable) + 32(arBuckets) = 86 个字节,作为一个变量应该在符号表中有个位置,也是一个数组元素,因此一个空数组变量需要 118 个字节来描述和存储。从空间的角度来看,小型数组平均代价较大,当然一个脚本中不会充斥数量很大的小型数组,可以以较小的空间代价来获取编程上的快捷。
但如果将数组当作容器来使用就是另一番景象了,实际应用经常会遇到多维数组,而且元素居多。比如10k个元素的一维数组大概消耗540k内存,而10k x 10 的二维数组理论上只需要 6M 左右的空间,但是按照 memory_get_usage 的结果则两倍于此,[10k,5,2]的三维数组居然消耗了23M,小型数组果然是划不来的。
PHP 相关文章推荐
论坛头像随机变换代码
Oct 09 PHP
php处理json时中文问题的解决方法
Apr 12 PHP
php join函数应用
May 04 PHP
PHP goto语句简介和使用实例
Mar 11 PHP
PHP实现支持GET,POST,Multipart/form-data的HTTP请求类
Sep 24 PHP
php中session与cookie的比较
Jan 27 PHP
php实现过滤UBB代码的类
Mar 12 PHP
php中smarty变量修饰用法实例分析
Jun 11 PHP
php析构函数的简单使用说明
Aug 24 PHP
php简单压缩css样式示例
Sep 22 PHP
php 多文件上传的实现实例
Oct 23 PHP
PHP PDOStatement::fetchAll讲解
Jan 31 PHP
PHP UTF8编码内的繁简转换类
Jul 20 #PHP
php 验证码制作(网树注释思想)
Jul 20 #PHP
php PDO中文乱码解决办法
Jul 20 #PHP
PHP 配置文件中open_basedir选项作用
Jul 19 #PHP
PHP form 表单传参明细研究
Jul 17 #PHP
php与php MySQL 之间的关系
Jul 17 #PHP
php 图片上传类代码
Jul 17 #PHP
You might like
PHP中的strtr函数使用介绍(str_replace)
2011/10/20 PHP
[原创]ThinkPHP让../Public在模板不解析(直接输出)的方法
2015/10/09 PHP
PHP中file_exists使用中遇到的问题小结
2016/04/05 PHP
PHP中phar包的使用教程
2017/06/14 PHP
jquery 学习之二 属性(html()与html(val))
2010/11/25 Javascript
判断滚动条到底部的JS代码
2013/11/04 Javascript
浅谈JavaScript数据类型及转换
2015/02/28 Javascript
JavaScript中消除闭包的一般方法介绍
2015/03/16 Javascript
JQuery之proxy实现绑定代理方法
2016/08/01 Javascript
原生js实现网易轮播图效果
2020/04/10 Javascript
深入理解javascript中的 “this”
2017/01/17 Javascript
JavaScript编写九九乘法表(两种任选)
2017/02/04 Javascript
JS设计模式之状态模式概念与用法分析
2018/02/05 Javascript
Javascript中parseInt的正确使用方式
2018/10/17 Javascript
详解django模板与vue.js冲突问题
2019/07/07 Javascript
python简单实现刷新智联简历
2016/03/30 Python
python使用tcp实现局域网内文件传输
2020/03/20 Python
Atom Python 配置Python3 解释器的方法
2019/08/28 Python
python实现多线程端口扫描
2019/08/31 Python
Python3.5 win10环境下导入kera/tensorflow报错的解决方法
2019/12/19 Python
解决Keras的自定义lambda层去reshape张量时model保存出错问题
2020/07/01 Python
基于opencv的selenium滑动验证码的实现
2020/07/24 Python
关于PyCharm安装后修改路径名称使其可重新打开的问题
2020/10/20 Python
千禧酒店及度假村官方网站:Millennium Hotels and Resorts
2019/05/10 全球购物
外贸专业求职信
2014/03/09 职场文书
法制宣传月活动总结
2014/04/29 职场文书
项目建议书范文
2014/05/12 职场文书
企业贷款委托书格式
2014/09/12 职场文书
司法局群众路线教育实践活动整改措施
2014/09/17 职场文书
公司领导班子民主生活会对照检查材料
2014/10/02 职场文书
商铺租房协议书范本
2014/12/04 职场文书
员工辞职信怎么写
2015/02/27 职场文书
2015年社区党建工作汇报材料
2015/06/25 职场文书
2016年社区文体活动总结
2016/04/06 职场文书
React如何创建组件
2021/06/27 Javascript
工厂无线对讲系统解决方案
2022/02/18 无线电