簡單瞭解一下php的迭代生成器yield

OldBoy~發表於2018-07-05

yield是從PHP5.5開始有的,關於yidle的說明鳥哥的部落格做了詳細說明,我覺得是有點複雜,在看了幾篇其他的帖子還有案例,我大概知道yield的作用就是在做大量資料迴圈處理的時候,能節省很大一部分記憶體~

官方:http://php.net/manual/zh/language.generators.syntax.php

鳥哥:http://www.laruence.com/2015/05/28/3038.html

參考案例說明yield的作用

<?php
 //普通模式的程式碼
function generateData($max)
{
 $arr = [];
 for ($i = 0; $i <= $max; $i++) {
 $arr[] = $i;
 }
}
 
echo '開始前記憶體佔用:' . memory_get_usage() . PHP_EOL;
$data = generateData(100000);
echo '生成完陣列後記憶體佔用:' . memory_get_usage() . PHP_EOL;
unset($data);
echo '釋放後的記憶體佔用:' . memory_get_usage() . PHP_EOL;
# php yield.php 
開始前記憶體佔用:387600
生成完陣列後記憶體佔用:387632
釋放後的記憶體佔用:387632

前後使用的記憶體差值為:387632-387600 = 32

# php yield.php 
開始前記憶體佔用:386912
生成完陣列後記憶體佔用:387520
釋放後的記憶體佔用:386944

前後使用的記憶體差值為:387520-386912 = 608

明顯608要遠遠大於32,不是說是降低記憶體使用率麼。那麼就把迴圈的數值調大試試。把100000改為10000000

再使用cli模式執行,發現不適用yield會報錯了

PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 134217736 bytes) in /data/wwwroot/default/up_sql.php on line 7

但是yield依然是608,這是因為它自身,它在你進行迭代的時候才會產生真實資料。

所以如果你的資料來源非常大,那麼用 yield 吧。如果資料來源很小,當然選擇一次載入記憶體。

相關文章