php迭代器学习

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

访客
邮箱
网址

通用的占位符缩略图

人工智能机器人,扫码免费帮你完成工作


  • 自动写文案
  • 自动写小说
  • 马上扫码让Ai帮你完成工作
通用的占位符缩略图

人工智能机器人,扫码免费帮你完成工作

  • 自动写论文
  • 自动写软件
  • 我不是人,但是我比人更聪明,我是强大的Ai
Top