什么是生成器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 . "\n";
}
//var_dump(iterator_to_array($iterate));
}
if ($argc === 2) {
$test = range(0, $num, 1);
foreach ($test as $value) {
echo $value . "\n";
}
}
$end = xdebug_memory_usage(); echo sprintf("内存消耗量%s\n", 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

PHP 生成器Generators的入门理解和学习的更多相关文章

  1. 深入浅出ES6(十一):生成器 Generators,续篇

    作者 Jason Orendorff  github主页  https://github.com/jorendorff 欢迎回到深入浅出ES6专栏,望你在ES6探索之旅中收获知识与快乐!程序员们在工作 ...

  2. MongoDB索引(一) --- 入门篇:学习使用MongoDB数据库索引

    这个系列文章会分为两篇来写: 第一篇:入门篇,学习使用MongoDB数据库索引 第二篇:进阶篇,研究数据库索引原理--B/B+树的基本原理 1. 准备工作 在学习使用MongoDB数据库索引之前,有一 ...

  3. 免考final linux提权与渗透入门——Exploit-Exercise Nebula学习与实践

    免考final linux提权与渗透入门--Exploit-Exercise Nebula学习与实践 0x0 前言 Exploit-Exercise是一系列学习linux下渗透的虚拟环境,官网是htt ...

  4. 利用Theano理解深度学习——Multilayer Perceptron

    一.多层感知机MLP 1.MLP概述 对于含有单个隐含层的多层感知机(single-hidden-layer Multi-Layer Perceptron, MLP),可以将其看成是一个特殊的Logi ...

  5. 【OpenFOAM】——OpenFOAM入门算例学习

    1  明确目标——为啥费老大劲儿学习OpenFOAM 学习OpenFOAM主要出于课题需要,希望实现以下几个目标: l  [ ]学会用SnappyHexMesh生成高质量网格: l  [ ]学习使用O ...

  6. Linux系统的理解及学习Linux内核的心得

    作业列表      (点击作业跳转) linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作 linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核 ...

  7. Struts2入门3 深入学习

    Struts2入门3 深入学习 处理结果和异常 前言: Struts学习的差不多了,还有最后的一点就收官了就是结果处理和异常处理.前面学习Struts主要围绕就是Action以及struts.xml配 ...

  8. 【特别推荐】Node.js 入门教程和学习资源汇总

    这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...

  9. 关于HTML中,绝对定位,相对定位的理解...(学习HTML过程中的小记录)

    关于HTML中,绝对定位,相对定位的理解...(学习HTML过程中的小记录)   作者:王可利(Star·星星) HTML中 相对定位:position:relative; 绝对定位:position ...

随机推荐

  1. poj 3621(最优比率环)

    Sightseeing Cows Farmer John has decided to reward his cows for their hard work by taking them on a ...

  2. securecrt中vim行号下划线问题及SecureCRT里root没有高亮的设置,修改linux终端命令行颜色

      背景:在用raspberry用SecureCRT下的vim打开文件时出现用set nu时行有下划线,于是找了下解决办法,如下:vim行号下划线问题在vim中发现开启显示行号(set number) ...

  3. 830C

    分块+二分 这道题思路很巧妙 我们大概可以推出一个式子sigma(d-[(ai-1)%d+1])<=k,要求求出d的最大值 然后我们化简一下,sigma(d-[(ai-1)-[(ai-1)/d] ...

  4. request.getRemoteAddr()和request.getRemoteHost()

    转自:https://www.cnblogs.com/aizj/p/7593209.html request.getRemoteAddr()是获得客户端的ip地址.request.getRemoteH ...

  5. 安装Git(转载)

    转自:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137396287703 ...

  6. E20171212-hm

    odd   adj. 古怪的; 奇数的; 剩余的; 临时的; odd number 奇数 even adj. 偶数的 even number 偶数

  7. poj Find a multiple【鸽巢原理】

    参考:https://www.cnblogs.com/ACShiryu/archive/2011/08/09/poj2356.html 鸽巢原理??? 其实不用map但是习惯了就打的map 以下C-c ...

  8. 洛谷 P3437 [POI2006]TET-Tetris 3D

    二维线段树区间更新啊 树套树的外层树,如果是线段树的话一般似乎不能打标记?(毕竟标记不好下传) 然而起码对于这题是可以的...对于外层线段树,每个节点放两个内层线段树dat和setv,分别是得到的值和 ...

  9. js实现水波纹背景

    <!DOCTYPE html> <html> <head> <title>水波背景</title> <meta charset=&qu ...

  10. Docker学习系列(二):Docker三十分钟快速入门(上)

    一.背景 ​ 最近,Docker技术真是一片火热,它的出现也弥补了虚拟机资源消耗过高的问题,直接让虚拟化技术有了质的飞跃.那么本文我们来聊一聊Docker,和大家一起认识Docker,简单入门Dock ...