php官方已经提供了Iterator(迭代器)接口,通过网上资料的学习,目前看适合超大集合或者数组提取使用。学习一个函数的实现对比内存占用差距.
使用迭代器和普通循环实现range()函数。
(1).普通循环实现range()函数。
function newrange($low, $hign, $step = 1) { $ret = []; for ($i = 0; $i < $hign; $i += $step) { $ret[] = $i; } return $ret; } //统计内存占用 $oldMemory = memory_get_usage(); $result = newrange(0, 500000); $newMemory = memory_get_usage(); $useMemory = $newMemory - $oldMemory; echo 'used:' . $useMemory . 'byte';
used:14680128byte
(1).迭代器实现range()函数。
class newrange implements Iterator { protected $low; protected $high; protected $step; protected $current; public function __construct($low, $high, $step = 1) { $this->low = $low; $this->high = $high; $this->step = $step; } //返回到迭代器的第一个元素 public function rewind() { var_dump('rewind'); $this->current = $this->low; } //向前移动到下一个元素 public function next() { var_dump('next'); $this->current += $this->step; } //返回当前元素 public function current() { var_dump('current'); return $this->current; } //返回当前元素的键 public function key() { var_dump('key'); return $this->current + 1; } //检查当前位置是否有效 public function valid() { var_dump('valid'); return $this->current <= $this->high; } } //统计内存占用 $oldMemory = memory_get_usage(); $result = new newrange(0, 9, 1); /* foreach ($result as $key => $value) { } */ $newMemory = memory_get_usage(); $useMemory = $newMemory - $oldMemory; echo 'used:' . $useMemory . 'byte';
used:96byte
再来使用php自带的pdo实现的迭代器测试大数据占用内存.
(1).数据是我们公司正式服务器拉取下拉的,保证数据不是随便生成的,之前在迁移数据使用mysqli提取单表53w数组内存超过限制(每条记录字段50个)。
(2).本次改用pdo的query方法,因为query内部用php迭代器实现
//起始内存 $oldMemory = memory_get_usage(); $host = '127.0.0.1:9944'; $datebase = 'dev_dnet1'; $username = 'dev_dnet2'; $password = 'dev_dnet3'; $conn = "mysql:host=$host;dbname=$datebase"; $db = new PDO($conn, $username, $password); $sql = 'select * from prd_product'; $result = $db->query($sql); //结束内存 $newMemory = memory_get_usage(); $useMemory = $newMemory - $oldMemory; echo 'used:' . $useMemory . 'byte';
used:1563928408byte 1491M
总结:
(1).迭代器仅仅只是产生1个对象的内存,因此在使用超大数组的时候可以选择迭代器,只不过使用起来麻烦点,但是至少比使用数组性能好多了。
(2).如果想要看到内部执行过程只需要使用foreach直接循环结果集,php内部帮我们执行了对应方法来实现迭代
(3).PHP数组的内存利用率只有 1/10,但是我们可以用迭代器啊,世界上最好的编程语言
<?php $base64_body = substr(strstr($_POST[base64],','),1); $data= base64_decode($base64_body); file_put_contents($_SERVER[&q...
PHP验证码不显示的问题应该是经常的事情,我在这里把2种解决方案都发出来方便大家后期使用.因为是昨天晚上自己写验证码都没有显示,我就直接把之前和李炎恢老师上课写的验证码拿来还是不显示,醉了。首先是第一种方法:1、打开服务器安装目录下的php.ini文件;2、去掉;extension=php_gd.d...
开启错误提示代码:ini_set("display_errors", "On"); error_reporting(E_ALL | E_STRICT);关闭错误提示代码:error_reporting(E_ALL ^&n...
第一次听说端口复用是在mixphp最新版本中发现的,mixphp启动监听9501端口,现在作者说可以多开几个进程来执行mixphp,我心里想了下再启动不是会端口冲突嘛,但是却没有问题,于是下载mixphp的源码解读,原来是启动http服务器使用new Co\Http\Server('0.0....
PHP简单定时器可以通过pcntl_signal创建闹钟信号来实现。但是缺点很明显,性能一般,要自己实现守护进程,不支持毫秒级定时器,单进程不支持多个闹钟信号,不能跨平台运行event扩展支持的事件多,性能高。<?php //创建event配置.[空配置] $eventConfig ...
本教程使用的定时任务基于EasyTak,EasyTask官方文档:https://gitee.com/392223903/EasyTask(1).安装tp5.0或者5.1composer create-project topthink/think=5.0.* tp5&n...