1、迭代生成器
生成器的核心是一个yield关键字,一个生成器函数看起来像一个普通的函数,不同的是:普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值。生成器函数被调用时,返回的是一个可以被遍历的对象。
yield和return有点类似,不过不同的是,return会返回值并且终止代码的执行,而yield会返回一个值给循环调用此生成器的代码并且只是暂停执行生成器函数。

function gen_one_tow_three(){
for($i = 1; $i <=3; $i++){
//注意:变量$i的值在不同的yield之间是保持传递的。
yield $i;
}
}
$generator = gen_one_tow_three();
var_dump($generator);
echo "<br>";
var_dump($generator instanceof Iterator);
echo "<br>";
foreach($generator as $value){
echo $value."\n";
}

输出:
object(Generator)#1 (0) { }
bool(true)
1 2 3
调用gen_one_tow_three()的时候,里面的代码并没有真正的执行,而是返回一个生成器对象$generator = Generator Object(),$generator instanceof Interator说明Generator事项了Iterator接口,可以用foreach进行遍历,每次遍历都会隐式调用current()、next()、key()、valid()等方法。(Generator类中的方法)
2、处理大数据
下面通过实现一个xrange函数来简单说明:

function xrange($start,$end,$step = 1){
for ($i=$start; $i <=$end; $i+=$step) {
yield $i;
}
} foreach(xrange(1,1000000) as $num){
echo $num,"\n";
}

上面这个xrange()函数提供了和php的内建函数range()一样的功能,但不同的是range()函数返回的是一个包含值从1到100w的数组,而xrange()函数返回的是依次输出这些值得一个迭代器,而不会真正以数组形式返回。
这种方法的优点是显而易见的,它可以让你在处理大数据集合的时候不用一次性的加载到内存中。甚至你可以处理无限大的数据流
3、处理大文件
在PHP读取大文件的时候,经常会出现内存不足的情况,如果文件过大的话,没法一次读取玩,采用yield来实现大文件的读取。
3.1)老式读取

function readLocalFile($fileName){
$handle = fopen($fileName,'r');
$lines = [];
while(!feof($handle)){
$lines[] = fgets($handle);
}
fclose($handle);
return $lines;
}

3.2)yield读取方式

function readYieldFile($fileName){
$handle = fopen($fileName,'r');
while(!feof($handle)){
yield fgets($handle);
}
fclose($handle);
}

//为了便于测试,写一个读取内存的辅助函数

function formatBytes($bytes){
if($bytes<1024){
return $bytes . "b";
}else if($bytes <1048576){
return round($bytes / 1024,2) ."kb";
}
return round($bytes / 1048576,2) . "mb";
}
//第一种,all.zip是一个158M的压缩文件
readLocalFile('./all.zip');
echo formatBytes(memory_get_peak_usage());

报错:Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 123 bytes) in

//第二种
$lines = readYieldFile('./all.zip');
foreach($lines as $row){}
echo formatBytes(memory_get_peak_usage());

输出:141.3kb

总结:
使用老式读取,返回的是一个包含每行数据的数组,而yield方式则返回的事宜个迭代器,而不会以真正的数组返回。
这种方法的有点可以让你在处理大数据集合的时候不用一次性的加载到内存中,甚至可以处理无限大的数据流。

PHP迭代生成器---yield的更多相关文章

  1. python3使用迭代生成器yield减少内存占用

    技术背景 在python编码中for循环处理任务时,会将所有的待遍历参量加载到内存中.其实这本没有必要,因为这些参量很有可能是一次性使用的,甚至很多场景下这些参量是不需要同时存储在内存中的,这时候就会 ...

  2. 简单了解一下php的迭代生成器yield

    yield是从PHP5.5开始有的,关于yidle的说明鸟哥的博客做了详细说明,我觉得是有点复杂,在看了几篇其他的帖子还有案例,我大概知道yield的作用就是在做大量数据循环处理的时候,能节省很大一部 ...

  3. Python生成器 yield

    迭代器与list相比较,就for in句型循环拿数据而言: 用list写很简洁,但如果list数据过大,会很消耗资源. 用iteration 迭代器写,则不会消耗那么多资源.他会随用随取,用一个拿一个 ...

  4. Python入门之迭代器/生成器/yield的表达方式/面向过程编程

    本章内容 迭代器 面向过程编程 一.什么是迭代 二.什么是迭代器 三.迭代器演示和举例 四.生成器yield基础 五.生成器yield的表达式形式 六.面向过程编程 ================= ...

  5. PHP性能优化利器:生成器 yield理解

    如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生.但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...

  6. [PY3]——函数——生成器(yield关键字)

    函数—生成器篇 1. 认识和区分可迭代or生成器 1.1 可迭代对象 当你建立了一个列表,你可以逐项地读取这个列表,这叫做一个可迭代对象 当你使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代 ...

  7. 6 生成器 yield 协程

    1.生成器 ----> 1 b = [x*2 for x in range(100000000000)] MemoryError: 想生成一个存放很多数据的列表,但是又不想内存占用太多 每次用一 ...

  8. day4 内置函数 迭代器&生成器 yield总结 三元运算 闭包

    内置函数: 内置函数 # abs()返回一个数字的绝对值.如果给出复数,返回值就是该复数的模. b = -100 print(b) print(abs(b)) # all() 所有为真才为真,只要有一 ...

  9. php生成器yield

    上次说了php的生成器Iterator,这次说一下yield 迭代生成器 (迭代)生成器也是一个函数,不同的是这个函数的返回值是依次返回, 而不是只返回一个单独的值.或者,换句话说,生成器使你能更方便 ...

随机推荐

  1. go无缓冲通道

    package main import ( "fmt" "math/rand" "sync" "time" ) //wg ...

  2. ajax 提交 form表单 ,后台执行两次的问题

      网上大多的答案是说同步不同步的问题,但是我把异步改成同步也不行.async: false,   // 单击时表单检查 $('.btn-next a').click(function () { if ...

  3. 使用requirejs+vue 打造 无需编译发布便捷修改调整的模块开发方案 (一)

    前言 不知道大家有没有这种感觉,现在流行的很多前端技术,基本上都基于webpack编译,当然不是说这种方案不好,在标准的开发流程运行中,这种方式其实也挺不错,管理方便,代码统一. 痛点:项目不是单独针 ...

  4. HADOOP回顾

    1. hadoop 分为四大模块 common  其他组件的公共一来模块 HDFS 分布式模块提供高吞吐量的数据访问 mapreduce 分布式计算模块 yarn 作业调度和集群资源管理模块 2. 安 ...

  5. SWT界面刷新

    参考文章: https://segmentfault.com/q/1010000002956350 在UI线程sleep等待,是不会刷新界面的.   outPrint.setText("其他 ...

  6. Bitmap之getPixel和setPixel函数

    package com.loaderman.customviewdemo; import android.app.Activity; import android.graphics.Bitmap; i ...

  7. 123457123457---com.threeObj03.MaJiangertong--- 记忆翻牌益智游戏

    com.threeObj03.MaJiangertong--- 记忆翻牌益智游戏

  8. Ubuntu 16.04 haproxy + keeplive

    WEB架构

  9. win10系统安装踩坑之路

    1.一定要下载win10原版镜像.如果用迅雷下载一定要校验文件hash值的完整性,可以用fhash.exe校验,如果哈希值不一致,一定要重新下载镜像. 2.用软媒U盘启动制作启动U盘 3.重启后按F1 ...

  10. 异步回收fork出的子进程(僵尸进程)

    #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h&g ...