PHP 性能优化:生成器 yield 的初体验
需求:用户发贴,粉丝收到通知。
了解了一下生成器,就用一下,虽然理解的还不是很深刻。
<?php
namespace App\Jobs;
use App\Models\User;
use App\Models\UserFollow;
use App\Notifications\NewThread;
class NewThreadNotification extends Job {
/** @var mixed */
private $thread;
private $actor;
public function __construct($thread,$actor) {
$this->thread = $thread;
$this->actor = $actor;
}
public function handle()
{
app('log')->info('----粉丝通知--这里是发送通知队列-----');
//获取这个用户的所有粉丝
$follow = UserFollow::query()
->where('to_user_id',$this->thread->user_id)
->with('fromUser')
->get();
$users = $this->getFollowUser($follow);
foreach ($users as $v){
//发送微信通知
$v->fromUser->notify(new NewThread($this->actor,$this->thread));
}
app('log')->info('----粉丝通知--发送完成-----');
$this->delete();
}
public function getFollowUser($follow)
{
foreach ($follow as $v){
yield $v;
}
}
}
还在考虑,要不要分组,目前粉丝量顶天几万。以上是初体验。。。
分片处理:

laravel cursor()处理:

cursor()源码也看了一下,我猜laravel里面的懒加载应该是这个原理;



本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
如果这就是你的正式代码,那不是平白浪费资源吗?生成器也没用上呀
也许你要的是这样?
@renxiaotu
这是我改之前的,我觉得在循环里里面放 sql 查询不是很科学,还有你这样我得看看先 :sweat_smile:
这样写没啥用啊
@ 比如按照下面的写法,假设数据总量10000条,每次查询100条,共查100次,那内存最大占用就是100条数据,如果你换成生成器,这个情况有什么改观呢?
@你的这句就已经把10000条数据读到内存了,后面的循环无论什么方案都一样
@renxiaotu 这里开始理解了,那我重要的是发送通知这个操作啊。这也没用吗
可以先理解 yeild,再运用到项目中 php中yield的用法
建议用 chunk
关于 laravel cursor 原理,参考如下代码:
@喝卵形 昨天我看了一下这个源码,大概就是这样子的。 :smile:
:joy: 官网生成器举例 range 那个例子只是为了举例。官网的那个例子是可以用
for($i=0;$i<100;$i++)完美代替的。生成器主要还是有点甜吧。感觉你说的场景不是很需要生成器。 生成器 这个名字很好的 。生成调用的时候代表生成数据。其实和性能优化不是强关联。一些场景用 生成器可以优化代码,写的好看一些。比如之前我读csv文件用 yeild 封装了一下,每次调用读一行。代码也比较好看。不过要说不用生成器。其他写法也可以做到内存,速度上相差无几