日韩精品欧美激情国产一区_中文无码精品一区二区三区在线_岛国毛片AV在线无码不卡_亞洲歐美日韓精品在線_使劲操好爽好粗视频在线播放_日韩一区欧美二区_八戒八戒网影院在线观看神马_亚洲怡红院在线色网_av无码不卡亚洲电影_国产麻豆媒体MDX

php中性優(yōu)化生成器

時間:2017-12-13 15:17:15 類型:PHP
字號:    

PHP生成器是5.5.0引入的功能,生成器實際上就是簡單的迭代器。生成器會根據(jù)需求計算產(chǎn)出迭代的值,而標準的PHP迭代器經(jīng)常在內(nèi)存中執(zhí)行迭代操作,這要預(yù)先計算出數(shù)據(jù)集,性能較低。如果使用特定的防護計算大量數(shù)據(jù),可以使用生成器,即時計算并產(chǎn)出后續(xù)值,不占用內(nèi)存。

創(chuàng)建生成器

生成器從不返回值,只是產(chǎn)出值。

<?php  function myGenerator() { 
    yield 'v1'; 
    yield 'v2'; 
    yield 'v3'; 
} 

調(diào)用生成器函數(shù)時,PHP會反悔一個屬于Generator類的對象。這個對象是可以foreach迭代的。每次迭代,PHP要求這個實例計算并提供下一個要迭代的值。

每次產(chǎn)出一個值,生成器的內(nèi)部狀態(tài)都會停頓。向生成器請求下一個值時,內(nèi)部狀態(tài)才會恢復(fù)。這種停頓-恢復(fù)的狀態(tài)會一直持續(xù)下去。

<?php  foreach (myGenerator() as $yieldValue) { 
    echo $yieldValue , PHP_EOL; 
} 

使用生成器

<?php  function makeRange($length) { 
    $dataset = []; 
    for ($i = 0$i < $length$i++) { 
        $dataset[] = $i; 
    } 
     
    return $dataset; 
} 
  $customRange = makeRange(1000000);  foreach ($customRange as $i) { 
    echo $iPHP_EOL; 
} 

上面的這個方法并沒有善用內(nèi)存,使用生成器只會為一個整數(shù)分配內(nèi)存。

<?php  function makeRange($length) { 
    for ($i = 0$i < $length$i++) { 
        yield $i; 
    } 
} 
  foreach(makeRange(1000000as $i) { 
    echo $iPHP_EOL; 
} 

應(yīng)用場景

很多PHP開發(fā)者不了解生成器,其實主要是不了解應(yīng)用場景。那么,生成器在實際開發(fā)中有哪些應(yīng)用?

PHP開發(fā)很多時候都要讀取大文件,比如csv文件、txt文件,或者一些日志文件。這些文件如果很大,比如5個G。這時,直接一次性把所有的內(nèi)容讀取到內(nèi)存中計算不太現(xiàn)實。

這里生成器就可以派上用場啦。簡單看個例子:

<?php  function getRows($file) { 
    $handle = fopen($file'rb'); 
    if ($handle === false) { 
        throw new Exception(); 
    } 
     
    while (feof($handle) === false) { 
        yield fgetcsv($handle); 
    } 
    fclose($handle); 
} 
  foreach (getRows('data.csv'as $row) { 
    print_r($row); 
} 

這個例子中,生成器只會為CSV文件分配一行內(nèi)存,而不是讀入整個文件到內(nèi)存。使用生成器讀取文件,第一次讀取了第一行,第二次讀取了第二行,以此類推,每次被加載到內(nèi)存中的文字只有一行,大大的減小了內(nèi)存的使用。這樣,即使讀取上G的文本也不用擔心,完全可以像讀取很小文件一樣編寫代碼。