当前位置:首页 > PHP > 正文内容

php迭代器学习

高老师7年前 (2018-07-25)PHP1770

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,但是我们可以用迭代器啊,世界上最好的编程语言

扫描二维码推送至手机访问。

版权声明:本文由高久峰个人博客发布,如需转载请注明出处。

本文链接:https://blog.20230611.cn/post/65.html

分享给朋友:

“php迭代器学习” 的相关文章

php base64保存为图片偷懒版本

php base64保存为图片偷懒版本

<?php $base64_body = substr(strstr($_POST[base64],','),1); $data= base64_decode($base64_body); file_put_contents($_SERVER[&q...

PHP验证码不显示的终极解决方案

PHP验证码不显示的终极解决方案

PHP验证码不显示的问题应该是经常的事情,我在这里把2种解决方案都发出来方便大家后期使用.因为是昨天晚上自己写验证码都没有显示,我就直接把之前和李炎恢老师上课写的验证码拿来还是不显示,醉了。首先是第一种方法:1、打开服务器安装目录下的php.ini文件;2、去掉;extension=php_gd.d...

php 开启错误提示,php 关闭错误提示

php 开启错误提示,php 关闭错误提示

开启错误提示代码:ini_set("display_errors", "On"); error_reporting(E_ALL | E_STRICT);关闭错误提示代码:error_reporting(E_ALL ^&n...

php端口复用,php socket端口复用

php端口复用,php socket端口复用

第一次听说端口复用是在mixphp最新版本中发现的,mixphp启动监听9501端口,现在作者说可以多开几个进程来执行mixphp,我心里想了下再启动不是会端口冲突嘛,但是却没有问题,于是下载mixphp的源码解读,原来是启动http服务器使用new Co\Http\Server('0.0....

php通过event扩展创建定时器,php毫秒级定时器

php通过event扩展创建定时器,php毫秒级定时器

PHP简单定时器可以通过pcntl_signal创建闹钟信号来实现。但是缺点很明显,性能一般,要自己实现守护进程,不支持毫秒级定时器,单进程不支持多个闹钟信号,不能跨平台运行event扩展支持的事件多,性能高。<?php //创建event配置.[空配置] $eventConfig ...

 thinkphp5定时任务,tp5定时任务,thinkphp定时任务,php定时任务,php定时器

thinkphp5定时任务,tp5定时任务,thinkphp定时任务,php定时任务,php定时器

本教程使用的定时任务基于EasyTak,EasyTask官方文档:https://gitee.com/392223903/EasyTask(1).安装tp5.0或者5.1composer create-project topthink/think=5.0.* tp5&n...