php foreach 遍历数据遇到的问题
来源:互联网 发布:wind数据库有免费版吗 编辑:程序博客网 时间:2024/06/14 14:13
用foreach遍历一个含有1001个元素的数组:
function get_memory(){ echo memory_get_usage() . PHP_EOL;}$arr = range(1, 10001);echo "before traversal :";get_memory();$begin = microtime(true);foreach ($arr as $key => $val) { $t = $val; if ($key % 2000 == 0) { get_memory(); } }echo "after traversal :";echo get_memory();echo microtime(true) - $begin . PHP_EOL;执行结果:
before traversal :2791328
2792000
2792000
2792000
2792000
2792000
2792000
after traversal :2792000
0.0026109218597412
第二段代码再$arr赋值下面多了一行对$foo变量指向$arr的代码,由php内核的cow机制可以知道两个变量会指向同一份数据,但执行结果却有很大区别:
$arr = range(1, 10001);$foo = $arr;echo "before traversal :";get_memory();$begin = microtime(true);foreach ($arr as $key => $val) { $t = $val; if ($key % 2000 == 0) { get_memory(); } }echo "after traversal :";echo get_memory();echo microtime(true) - $begin . PHP_EOL;before traversal :2791696
4123912
4123912
4123912
4123912
4123912
4123912
after traversal :2792400
0.0047910213470459
仅仅多了一行赋值代码,从内存和时间上可以推断出,foreach的时候好像进行了内存复制。要探究具体原因,需要在源码中找到答案,鸟哥之前写过一篇关于foreach的博客http://www.laruence.com/2008/11/20/630.html,引用其中的对foreach的生成的opcode。
opcode可以看出forearh执行了一个叫FE_RETSET操作。在php内核中该操作会将数组hashtable内部的指针指向其头部,在这一步操作过程中当数组的引用计数不大于1时(如上面代码就$arr一个变量指向数组),操作就在当前数组上进行,但当引用计数器大于1的时候,reset操作如果再在同一份数组上进行的时候会影响其他变量(如代码中的$foo),所以数组需要分裂复制了一份临时数组,待循环结束后又释放掉。 由于数组的复制,导致了内存的使用量和代码执行时间的增加,所以在代码中对大数据的遍历操作中最好不要给数据赋值给多个变量。
- php foreach 遍历数据遇到的问题
- php foreach 二维数组遍历下标问题
- 遇到的问题-----c#操作mongodb用foreach遍历集合报错curcor not found
- PHP foreach是如何遍历数组的?
- PHP中多维数组的foreach遍历
- PHP foreach遍历数组
- php 数组遍历foreach
- 使用 Java foreach 遇到的问题
- 关于mybatis中遇到的<foreach> 问题
- php在foreach中使用引用赋值&可能遇到的问题
- php之foreach遍历数组
- PHP中的foreach遍历数组
- PHP数组定义,foreach遍历
- PHP foreach数组循环的一些问题
- PHP foreach数组循环的一些问题
- PHP foreach()语句的一个诡异问题
- PHP foreach嵌套if else的问题
- 【PHP】数组foreach引发的小问题
- 【读书笔记】并发编程需要注意的几个典型问题
- 移动开发之浅析cocos2d-x的中文支持问题
- 自适应网页设计(Responsive Web Design)
- 阿里巴巴2010校园招聘技术类笔试试题
- OpenGL中的坐标系与矩阵
- php foreach 遍历数据遇到的问题
- 进程通信之二 管道技术第二篇 匿名管道
- JPEG图像的解压缩操作
- 在IT行业获得成功,你只需一项技能
- ExtJS(三)--Ajax实现省份城市联动
- 【Oracle】-【体系结构-DBWR】-DBWR进程相关理解
- Norlit OS —— 自制操作系统 第7章 进程调度
- hibernate入门学习心得
- mysql主从同步