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

php迭代器学习

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

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迭代器学习” 的相关文章

tp orm事务提交未执行的教训和总结

tp orm事务提交未执行的教训和总结

最近在项目中处理一个关于商品数据重复需要删除多余的商品记录,但是删除一条商品必然要把关联的其他表商品的id和其他商品信息更换为正确的,删除一个商品记录,同时要去修改100多张表的关联商品数据,在项目中引用了tp orm 1.2版本,由于项目是php5.6版本,没法使用最新orm,在代码中每处理1个商...

 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...

php关闭浏览器继续运行

php关闭浏览器继续运行

//设置客户端断开依然运行 ignore_user_abort(true); //设置脚本不超时 set_time_limit(0); //死循环每隔1秒访问一次网址 while (true) {     sleep(1);  &nb...

thinkphp断线重连

thinkphp断线重连

在编写thinkphp常驻内存的命令行应用中我们需要保证数据库连接不会断开,保证断开还能重新连接,因此大部分人的方案是直接修改tp的数据库配置文件database.php// 开启断线重连 'break_reconnect' => true,通常...

php序列化闭包函数,php反序列化闭包函数,php如何序列化/存储闭包(Closure)

php序列化闭包函数,php反序列化闭包函数,php如何序列化/存储闭包(Closure)

由于需要为自己的php守护进程投递闭包函数来执行,但是发现php官方根本没有提供php闭包函数的序列化功能。后来在mixphp文档发现了mixphp支持异步进程执行投递的闭包函数才发现了一个神奇的php闭包函数序列化composer包(1).安装序列化composer包composer r...

php levenshtein,php字符串编辑距离

php levenshtein,php字符串编辑距离

levenshtein函数可以计算两个字符串之间的编辑距离,那么何为编辑距离?编辑距离概念:编辑距离,是指两个字串之间,通过替换or插入or删除等操作将字符串str1转换成str2所需要操作的最少字符数量。 该算法的复杂度是 O(m*n),其中 n 和 m 分别是str1 和str2的长度注意:如果...