php yield 性能,PHP性能优化利器:生成器 yield

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

优点

生成器会对PHP应用的性能有非常大的影响

PHP代码运行时节省大量的内存

比较适合计算大量的数据

概念引入

来看一个普通php函数

/**

* 一个普通函数:把当前时间戳存入数组中

*/

function test($len)

{

$data = [];

for($i=0; $i

$data[] = time(); //把当前的时间戳存入数组中

}

return $data;

}

$d = test(10);

foreach($d as $val)

{

sleep(1); //暂停一秒

echo $val . '
';

}

得到的结果是:

bb1a4b5e0c3d

test.php

创建生成器

看下这段和刚刚很像的代码,我们删除了数组 $data ,而且也没有返回任何内容,而是在 time() 之前使用了一个关键字yield。

/**

* 一个普通函数:把当前时间戳存入数组中

*/

function test($len)

{

for($i=0; $i

yield time(); //把当前的时间戳存入数组中

}

}

$d = test(10);

foreach($d as $val)

{

sleep(1); //暂停一秒

echo $val . '
';

}

得出结果是:

bb1a4b5e0c3d

test.php

我们奇迹般的发现了,输出的值和第一次没有使用生成器的不一样。这里的值(时间戳)中间间隔了1秒。这里的间隔一秒其实就是 sleep(1) 造成的后果。但是为什么第一次没有间隔?那是因为:

未使用生成器时: test 函数内的 for 循环结果被很快放到 $data 中,并且立即返回。所以 foreach循环的是一个固定的数组。

使用生成器时: test 的值不是一次性快速生成,而是依赖于foreach 循环。 foreach 循环一次, for 执行一次。

到这里,你应该对生成器有点儿头绪。

yield实际开发应用

PHP开发很多时候都要读取大文件,比如csv文件、text文件,或者一些日志文件。这些文件如果很大,比如5个G。这时,直接一次性把所有的内容读取到内存中计算不太现实。

header("content-type:text/html;charset=utf-8");

function readTxt()

{

# code...

$handle = fopen("./test.txt", 'rb');

while (feof($handle)===false) {

# code...

yield fgets($handle);

}

fclose($handle);

}

foreach (readTxt() as $key => $value) {

# code...

echo $value.'
';

}

结果:

bb1a4b5e0c3d

图片.png

通过上图的输出结果我们可以看出代码完全正常。

但是,背后的代码执行规则却一点儿也不一样。使用生成器读取文件,第一次读取了第一行,第二次读取了第二行,以此类推,每次被加载到内存中的文字只有一行,大大的减小了内存的使用。

这样,即使读取上G的文本也不用担心,完全可以像读取很小文件一样编写代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值