0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PHP中的生成器

汽车电子技术 来源:程序猿零壹 作者:程序猿零壹 2023-01-20 10:44 次阅读
你好, 我是程序猿零壹。******

******今天要给大家带来php中yield的用法。对于yield,我相信大部分的人依旧是不会用,甚至不知道什么是yield。那么今天这篇文章就是来告诉大家有关于yield的一些用法,以及如何用yield来解决我们在php中遇到的问题。希望对大家有所帮助。******

******不知道大家有没有碰到过这样的问题,使用excel导入大量数据的时候会失败,并且提示以下错误信息:******

Fatal Error: Allowed memory size of xxxxxx bytes

******这个是因为在php程序中,是将变量存储在内存中。当从excel中要导入的数据量过大的时候,会出现内存不足的错误提示。

要解决这个问题,可以通过修改php中对于最大运行内存的设置:

ini_set('memory_limit', '200M');

但是这么做不能从根本上解决问题,当我们需要读取5g甚至更大文件的时候,我们的运行内存可能就吃不消了。

幸好,在php5.5之后提新增了生成器(Generators)特性,用于简化实现迭代器接口(iterator)创建简单的迭代器的复杂性。通过生成器,我们可以轻松的使用 foreach 迭代一系列的数据,而不需要事先在内存中构建要被迭代的对象,大大减少了内存的开销。

这样说可能比较抽象,不易于理解。所以我们先抛开有关于生成器的概念,先来看一个简单的例子。

$arr = range(1,100)

这里用到了range函数,它的作用是在内存中生成一个数组包含每个在指定范围内的值,并返回该数组。

如果我们自己来实现这样一个数组,应该怎么做呢?我们来看下面的代码:

function xrange($start,$end,$step=1){  
  $data = [];  
  for($i=$start;$i<$end,$i += $step) {    
    $data[] = $i;  
  }  
  return $data;
}
$start = memory_get_usage();
$data = xrange(1,1000);
foreach ($data as $value) {    
  echo $value.PHP_EOL;
}
$end = memory_get_usage();
echo "start:".$start.PHP_EOL;
echo "end:".$end.PHP_EOL;
echo "used:".($end - $start);

我们来看下start为1,end 分别为 10,100,1000,10000的情况下的内存消耗情况分别是怎么样的:

xrange(1,10); // used = 3480 0.0033187866210938MB
xrange(1,100); // used = 30168 0.028770446777344MB
xrange(1,1000); // used = 285144 0.27193450927734MB
xrange(1,10000); // used = 2957784 2.8207626342773MB

不难看出,随着$end的增大,所占用的内存也越来越大。

接下来我们来改造下xrange函数:

function xrange($start,$end,$step=1){  
  for($i=$start;$i<$end,$i += $step) {    
    yield $i;  
  }
}

我们删除了数组data,并且也删除了返回值,而在foreach的循环体里,在i前面添加关键字:yield。****

我们来看下改造之后的内存消耗:

xrange(1,10); // used = 256 0.000244140625MB
xrange(1,100); // used = 256 0.000244140625MB
xrange(1,1000); // used = 256 0.000244140625MB
xrange(1,10000); // used = 256 0.000244140625MB

Wow,这个结果令人惊讶。我们奇迹的发现了,内存消耗并没有随着$end的增大而增大,甚至是完全一样。

我们来还原一下代码的执行过程:

******首先调用xrange函数,传参$end=10,但是for循环了一次然后停止了,并且告诉foreach第一次循环可以用的值。


  1. ******foreach开始对$data循环,并使用for给的一个值执行输出。******
    
  2. ******foreach开始第二次循环,它向for循环又请求了一次******
    
  3. ******for循环又执行了一次,并将新的值告诉foreach
    

  4. ******foreach拿到第二个值,开始输出。
    

******所以,整个代码执行中,始终只有一个记录值参与循环,内存中也只有一条信息。


无论开始传入按的$end有多大,由于不会立即生成所有结果集,所以内存始终是一条循环的值,也就不会占用太大的内存了。

******看到这里,你是不是想说,“就这?”。生成器的用处当然不止这一些,还有其他的用武之地,比如协程。只不过因为本人才疏学浅,只能跟大家分享这么多了。大家感兴趣的话,可以看下鸟哥关于在php中使用协程实现多任务调度的文章。

好了,今天就到这里,如果大家觉得有用的话,不要忘记点赞收藏哦~

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 程序
    +关注

    关注

    114

    文章

    3629

    浏览量

    79495
  • 生成器
    +关注

    关注

    7

    文章

    301

    浏览量

    20183
  • PHP
    PHP
    +关注

    关注

    0

    文章

    451

    浏览量

    26445
收藏 人收藏

    评论

    相关推荐

    不同雷达目标生成器的架构及目标生成器的设计要求和准则

    雷达目标生成器的性能和能力以及它们测试雷达系统的可用性是关键,这主要取决于几个技术参数。本文介绍不同雷达目标生成器的架构,阐明适合雷达系统性能测试的目标生成器的设计要求和准则,同时给出测量结果举例。
    发表于 03-29 11:40 1534次阅读

    Minitab 交互式表格生成器

    生成器
    MinitabUG
    发布于 :2024年04月03日 15:58:54

    应用程序生成器

    我在生成应用程序的时候,右键点击程序生成规范,点击新建,只有源代码发布和web两项,没有应用程序,安装程序以及DLL和ZIP等,是因为我没有应用程序生成器的问题吗?那去哪可以整一个免费的LabVIEW2009 应用程序
    发表于 09-04 09:19

    如何去使用生成器

    生成器的工作原理是什么?如何去使用生成器呢?
    发表于 10-25 08:44

    python生成器

    了在大量数据下内存消耗过猛的问题。当你在 Python Shell 敲入一个生成器对象,会直接输出 generator object 提示你这是一个生成器对象>>> gen
    发表于 02-24 15:56

    pim卡资料生成器

    pim卡资料生成器
    发表于 11-22 23:23 6次下载

    汉语句子联想生成器

    在一定的语言环境中汉语词语之间存在着优先组合搭配关系,据此,在本文中利用互信息、数理统计和人脑联想记忆的相关理论,设计了一个汉语句子联想生成器,使用该生成器
    发表于 09-26 14:25 20次下载

    展频时脉生成器

    展频时脉生成器展频时脉的技术是频率调变( FM )的一种应用,相反地,频率调变通常会伴随生成展频的效果。展频时脉最基本的想法,是稍微地调变时脉讯号的频率,造成时脉讯
    发表于 02-26 11:05 23次下载

    自制酸奶生成器

    自制酸奶生成器
    发表于 04-23 11:48 878次阅读
    自制酸奶<b class='flag-5'>生成器</b>

    LED段码生成器

    本文提供的LED段码生成器,希望对你的学习有所帮助!
    发表于 06-03 15:19 96次下载

    代码生成器的应用

    jeesite框架代码生成器,可以很方便的生成代码,挺不错的。
    发表于 01-14 15:19 0次下载

    AN-113:精密坡道生成器

    AN-113:精密坡道生成器
    发表于 05-16 12:04 6次下载
    AN-113:精密坡道<b class='flag-5'>生成器</b>

    python生成器是什么

    python生成器 1. 什么是生成器生成器(英文名 Generator ),是一个可以像迭代器那样使用for循环来获取元素的函数。 生成器的出现(Python 2.2 +),实现
    的头像 发表于 02-24 15:53 3045次阅读

    Arduino赞美生成器

    电子发烧友网站提供《Arduino赞美生成器.zip》资料免费下载
    发表于 11-09 14:22 1次下载
    Arduino赞美<b class='flag-5'>生成器</b>

    通用RFID生成器

    通用RFID生成器资料分享
    发表于 02-10 15:35 1次下载