PHP循环超大数组很慢(40多分钟不到一半)怎么办?数组有52万条数据,18M多

金融数据,json格式,我用php处理为其他文本形式,给python matplotlib画图用(不会用python处理,只会画图)

数据为2015年全年外汇历史记录,精确到分钟(一年52万分钟),数据文本有18M大。

命令行执行后,开始循环非常快,半分钟一个月,然后越来越慢,到后来十分钟都跑不完一个月了。估计等不到它执行完毕了。为啥开始快后面就慢了?

下面是我代码,大家看看,怎么能让他执行快点
(其实这类数据用php处理不合适,但我只熟悉php其他不大懂没办法)

实在没办法只能把大数组人工拆分成十个小数组处理了。

  
header("content-Type: text/html;charset=Utf-8");
ini_set("memory_limit","512M");
date_default_timezone_set("Etc/GMT");

//include '2015.php'; //json数据,52万条,18M大,这里用下面的变量代替,就这种格式
$lishijson = '[{"time":"201501010203","high":1.21,"low":1.2099},"time":"201512311859","high":1.0871,"low":1.0869}]';
$lishiarr = json_decode($lishijson,true);

$dates = '['; //时间
$height = '['; //最高价
$low = '['; //最低价
foreach($lishiarr as $v){
$shijiancuo = strtotime($v['time']); //将时间转为时间戳,后面处理
$shijianYear = date('Y',$shijiancuo); //时间戳再转为时间
$shijianMonth = (int)date('m',$shijiancuo); //年
$shijianDay = (int)date('d',$shijiancuo); //月
$shijianShi = (int)date('H',$shijiancuo); //日
$shijianFen = (int)date('i',$shijiancuo); //时
echo $shijianMonth .'---'. $shijianDay . "\r\n"; //执行时输出看效果
$dates = $dates . 'datetime(' . $shijianYear .','. $shijianMonth .','. $shijianDay .','. $shijianShi .','. $shijianFen .'),';

$height = $height . $v['high'] . ',';
$low = $low . $v['low'] . ',';
}
//echo $dates; //生成python用时间
//echo $height;
//echo $low;

//生成数据存入文本
$myfile = fopen("2015.py", "w") or die("不能创建文件!");
$txt = 'dates = ' . $dates . "\r\n\r\n" . 'height = ' . $height . "\r\n\r\n" . 'low = ' . $low . "\r\n";
fwrite($myfile, $txt);
fclose($myfile);
评论 (0)链接2016-02-18 

这个明显有问题
$dates = '['; //时间
$height = '['; //最高价
$low = '['; //最低价
这三个变量会不断占用栈内存,

建议你在for each中增加变量,如下:
并且改变你的程序设计结构,先将三个变量分别输出到三个文本最后再合并,每个变量隔10000行(你自己看)输出一次

  
//include '2014.php';
$lishijson = '[{"time":"201501010203","high":1.21,"low":1.2099},{"time":"201512311859","high":1.0871,"low":1.0869}]';
$lishiarr = json_decode($lishijson,true);

$dates = '['; //时间
$height = '['; //最高价
$low = '['; //最低价

$aaa = fopen("dates.py", "w") or die("不能创建文件!"); //打开文件
$bbb = fopen("height.py", "w") or die("不能创建文件!"); //打开文件
$ccc = fopen("low.py", "w") or die("不能创建文件!"); //打开文件

$cnt = 0;//计数
foreach($lishiarr as $v){
$shijiancuo = strtotime($v['time']); //将时间转为时间戳,后面处理
$shijianYear = date('Y',$shijiancuo); //时间戳再转为时间
$shijianMonth = (int)date('m',$shijiancuo); //年
$shijianDay = (int)date('d',$shijiancuo); //月
$shijianShi = (int)date('H',$shijiancuo); //日
$shijianFen = (int)date('i',$shijiancuo); //时
echo $shijianMonth .'---'. $shijianDay . "\r\n"; //执行时输出看效果

$cnt ++;
$dates = $dates . 'datetime(' . $shijianYear .','. $shijianMonth .','. $shijianDay .','. $shijianShi .','. $shijianFen .'),';
$height = $height . $v['high'] . ',';
$low = $low . $v['low'] . ',';
if( 0==$cnt%10000 )//每10000行就输出到文本
{
fwrite($aaa,$dates);
fwrite($bbb,$height);
fwrite($ccc,$low);//打印到文件
$dates = null;
$height = null;
$low = null;
}
}

fclose($aaa);
fclose($bbb);
fclose($ccc);
dongzide
dongzide
174
编辑于 2016-03-10
该答案已被锁定,无法对其进行评论,编辑及投票。
()
评论 (4)链接 • 2016-02-19
  • 0 支持
    谢谢,回头试下,看你的代码是说我的程序执行越来越慢的原因是那三个变量的值越来越大了吗?
    所以如果隔一段时间设为null清空一次就好了?是这样吗?
    – dongzide 2016-02-19
  • 0 支持
    很有可能,先试一下,不行再讨论。 – 随我变suiwobian 2016-02-19
  • 0 支持
    帅呆了,我把代码照你的意思改了下(分号啥的,//最后数据写入这三句好像没用去掉了),52万数据跑完只用了2分钟多一点。昨天我把一个大数据拆分成3个小文件跑,一个跑下来好好几个小时。
    看来就是那三个变量循环后越来越大,所以就越来越慢,每10000条清零一下就好了。
    想问下为什么变量越变越大就会越来越慢,php这方面的原理是什么?
    – dongzide 2016-02-19
  • 1 支持
    和java类似,脚本语言都有自己的内存管理,你不去主动释放他,它就要自己去整理这些内存,管理的内容越多,他本身的消耗也就越大,而且内存管理的优先级肯定比你的代码高,所以只会越来越慢。
    http://www.laruence.com/2011/11/09/2277.html
    – 随我变suiwobian 2016-02-19

把52W数据分割 使用异步处理 或者php多线程
做过客户端大数据的都知道大容量数据要多线程 这是常识 php扩展插件就有多线程 也可以用php原生的异步处理同时处理多个数据 只要服务器不是小霸王520万数据和52万数据完全没区别
代码自找 只给方法

该答案已被锁定,无法对其进行评论,编辑及投票。
()
评论 (0)链接 • 2016-06-17
德问是一个专业的编程问答社区,请 登录注册 后再提交答案