zoukankan      html  css  js  c++  java
  • PHP 生成器Generators的入门理解和学习

    什么是生成器Generators

    生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值。

    一个简单的例子就是使用生成器来重新实现 range() 函数。 标准的 range() 函数需要在内存中生成一个数组包含每一个在它范围内的值,然后返回该数组, 结果就是会产生多个很大的数组。 比如,调用 range(0, 10000) 将导致内存占用超过 4 MB。

    例子代码

    <?php
    /**
     * Created by PhpStorm.
     * User: chenbotome@163.com
     * Date: 2018/7/30
     * Time: 上午11:29
     */
    $start = xdebug_memory_usage();
    $num = 10000;
    function rangeWithGenerators($start, $limit, $step = 1) {
        if ($start < $limit) {
            if ($step <= 0) {
                throw new LogicException('Step must be +ve');
            }
    
            for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } else { if ($step >= 0) {
                throw new LogicException('Step must be -ve');
            }
    
            for ($i = $start; $i >= $limit; $i += $step) {
                yield $i;
            }
        }
    }
    if ($argc === 1) {
        $iterate = rangeWithGenerators(0, $num, 1);
        foreach ($iterate as $value){
            echo $value . "
    ";
        }
        //var_dump(iterator_to_array($iterate));
    }
    if ($argc === 2) {
        $test = range(0, $num, 1);
        foreach ($test as $value) {
            echo $value . "
    ";
        }
    }
    $end = xdebug_memory_usage();
    
    echo sprintf("内存消耗量%s
    ", convert($end-$start));
    
    function convert($size){
        $unit=array('b','kb','mb','gb','tb','pb');
        return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
    }
    

    环境

    • PHP7.1
    • Xdebug

    执行命令

    • php test.php 结果返回:内存消耗量416 b
    • php test.php range 结果返回:内存消耗量4 mb

    测试结果论述

    • 通过代码的执行,比较除了PHP标准函数rang()和自定义函数rangeWithGenerators()之间的异同。实现了同样的目的,却消耗着不同的内存,生成器的优点显而易见。
    • rangeWithGenerators()使用了生成器,而生成器的关键就是使用yield关键词,yield常见的使用涉及到foreach和for两个流程控制语句。rangeWithGenerators()中for循环yield变量$i(yield可理解为生成-值,如同return可理解为返回-值)。
    • rangeWithGenerators()函数返回的便是一个生成器Generators( 使用var_dump($iterate)查看其类型 )。
    • 既然rangeWithGenerators()函数返回的是一个生成器,我们可以使用以下两种方式来使用:
    1. foreach循环该Generators,本例子中则使用该方法读取Generators。
    2. PHP标准函数iterator_to_array(),该函数将Generators转换为一个Array。

    使用场景,可查阅参考资料2

    参考资料:

    http://php.net/manual/zh/lang...
    实际生产中的使用

    原文地址:https://segmentfault.com/a/1190000015879089

  • 相关阅读:
    PAT 1006 Sign In and Sign Out
    PAT 1004. Counting Leaves
    JavaEE开发环境安装
    NoSql数据库探讨
    maven的配置
    VMWARE 下使用 32位 Ubuntu Linux ,不能给它分配超过3.5G 内存?
    XCODE 4.3 WITH NO GCC?
    在苹果虚拟机上跑 ROR —— Ruby on Rails On Vmware OSX 10.7.3
    推荐一首让人疯狂的好歌《Pumped Up Kicks》。好吧,顺便测下博客园可以写点无关技术的帖子吗?
    RUBY元编程学习之”编写你的第一种领域专属语言“
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9975539.html
Copyright © 2011-2022 走看看