上一次修改时间:2015-11-07 13:41:26

PHP数组内存占用测试

一般来说,PHP数组的内存利用率只有 1/10, 也就是说,一个在C语言里面100M 内存的数组,在PHP里面就要1G。

测试说明:测试文件为800W个带符号整数,PHP可用内存为1.5G;另外,memory_get_usage() 返回的结果并不是全是被数组占用了,还要包括一些 PHP 运行本身分配的一些结构


<?php
/*
 * PHP环境设置
 */
header("Content-type: text/html; charset=utf-8"); 
ini_set('memory_limit', '1536M');
ini_set('max_execution_time', 0);
/*
 * 文件生成,并输出函数执行时间
 */
//该文件中包含800W个有符号整数
$path = '/usr/local/apache/htdocs/test/data/int_800w.txt';
echo '文件大小为'.filesize($path),'<hr />';
echo '读取前内存使用:'.$read_front=memory_get_usage(),'<hr />';
$t1 = microtime(true);
// ... 执行代码 ...
$handle = fopen($path, 'r');
$str = fread($handle, filesize($path)); 
echo '读取后内存使用:'.$read_after=memory_get_usage(),'<hr />';
echo '读取消耗内存:'.($read_after-$read_front),'<hr />';
//将读取的字符串转化为数组
$arr = explode("\n", $str);
echo '数据转化为数组后内存使用:'.$explode_after=memory_get_usage(),'<hr />';
echo '读取消耗内存:'.($explode_after-$read_after),'<hr />';
sort($arr);
echo '内置函数(sort)排序后内存使用:'.memory_get_usage(),'<hr />';
$t2 = microtime(true);
echo '文件耗时'.round($t2-$t1,3).'秒';

测试结果为:

文件大小为74,220,572  (约74.22M)


读取前内存使用:228,072  (约0.22M)


读取后内存使用:74,458,352  (约74.45M)


读取消耗内存:74,230,280  (约74.23M)


数据转化为数组后内存使用:1,485,608,824 (约1485.60M)


读取消耗内存:1411150472  (约1411.15M)


内置函数(sort)排序后内存使用:1,485,608,960  (约1485.60M)


文件耗时57.204秒


结论:explode函数将字符串转化为数组的过程中会消耗掉字符串本身20倍的内存,但转化成功后,对数组进行排序时几乎不消耗内存;


直接生成数据测试,直接在内存中存入一个700W的数组

<?php
/*
 * PHP环境设置
 */
header("Content-type: text/html; charset=utf-8"); 
ini_set('memory_limit', '1024M');
ini_set('max_execution_time', 0);
echo '创建数组前'.$front=memory_get_usage(),'<hr />';
$arr = array();
for($i=0; $i<700; $i++){
        $str = '';
        for($j=0; $j<10000; $j++)
            $arr[] = rand(-50000000,50000000); 
}
echo '创建数组后'.$after=memory_get_usage(),'<hr />';
echo '该数组总共消耗内存:'.($after-$front);

测试结果:

创建数组前:222,288 (约0.22M)


创建数组后:1,019,332,032 (约1019.33M)


该数组总共消耗内存:1,019,109,744 (约1019.10M)

测试结果:一个700W的数组会消耗近1G的内存;(注:占用的内存与数据的值无关,随机数取值-500,500时也会占用近1G存)