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

php迭代器学习

高老师8年前 (2018-07-25)PHP2044

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高并发下数据库值更新的问题

PHP高并发下数据库值更新的问题

(1).创建数据库test ,创建表shop(字段id,total),商品id是1,商品总数10    (2).PHP模拟购买,商品数量大于0才能购买<?php //连接数据库 $con=mysqli_connect("192.168.2.18...

 php文件锁解决高并发

php文件锁解决高并发

前面的文章对于高并发下单商品导致商品库存为负值的问题请先阅读再阅读本篇文章一定对您有帮助,建议亲手测试较好。加上文件锁后的下单处理代码:【一】.阻塞模式:(如果其他进程已经加锁文件,当前进程会一直等其他进程解锁文件后继续执行)<?php //连接数据库 $con=mysqli_connect(...

php抽奖概率算法

php抽奖概率算法

<?php /*  *算法学习自百度.只是学习和记录  */ header("Content-type:text/html;charset=utf-8"); //1.设置奖项,id是奖项id,name是中奖名称,v是中奖概率 $arr =&n...

php非对称加密

php非对称加密

先在centos安装openssl,然后开始://生成私钥openssl genrsa -out rsa_private_key.pem 1024//生成公钥openssl rsa -in rsa_private_key.pem&...

php引用变量的完全理解

php引用变量的完全理解

在PHP中,大部分变量类型,如字符串,整型,浮点,数组等都是值类型的,而类和对象是引用类型.和其他语言有点差距.(1).在值类型中我们直接使用&符号表示指向对应变量的内存地址,当前变量和被指向的变量只要有1个的值被修改都会直接影响另外一个变量的值发生变化。(ps:还是非常节省内存的,可以使用...

 php监听事件,php触发事件

php监听事件,php触发事件

逛公众号文章看到文章"php实现事件监听与触发的方法,你用过吗?",我就好奇了,php又不是asp.net的webform,哪里来的服务端事件监听。于是学习了一波。先看下监听类:class Event {     /** &nbs...