版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第深入了解PHP中生成器yield的使用目錄1.什么是yield2.yield解決的問題3.yieldreturn的區(qū)別4.什么是yield選項(xiàng)5.生成器如果是做Python或者其他語言的小伙伴,對(duì)于生成器應(yīng)該不陌生。但很多PHP開發(fā)者或許都不知道生成器這個(gè)功能,可能是因?yàn)樯善魇荘HP5.5.0才引入的功能,也可以是生成器作用不是很明顯。但是,生成器功能的確非常有用。
1.什么是yield
生成器函數(shù)看上去就像一個(gè)普通函數(shù),除了不是返回一個(gè)值之外,生成器會(huì)根據(jù)需求產(chǎn)生更多的值。
看以下的例子:
functiongetValues(){
yield'value';
//輸出字符串"value"
echogetValues();
當(dāng)然,這不是他生效的方式,前面的例子會(huì)給你一個(gè)致命的錯(cuò)誤:類生成器的對(duì)象不能被轉(zhuǎn)換成字符串
2.yield解決的問題
解決運(yùn)行內(nèi)存的瓶頸,php程序中的變量存儲(chǔ)在內(nèi)存中,之前有遇到過讀取Excel文件時(shí)候,會(huì)出現(xiàn)內(nèi)存不足,出現(xiàn):
FatalError:Allowedmemorysizeofxxxxxxbytes
所以會(huì)設(shè)置php最大運(yùn)行內(nèi)存的設(shè)置:ini_set(memory_limit,200M)
但是當(dāng)我們讀取5g這么大的文件的時(shí)候,我們運(yùn)行內(nèi)存可能就吃不消了,所以會(huì)選擇yield
3.yieldreturn的區(qū)別
前面的錯(cuò)誤意味著getValues()方法不會(huì)如預(yù)期返回一個(gè)字符串,讓我們檢查一下他的類型:
functiongetValues(){
return'value';
var_dump(getValues());//string(5)"value"
functiongetValues(){
yield'value';
var_dump(getValues());//classGenerator#1(0){}
生成器類實(shí)現(xiàn)了生成器接口,這意味著你必須遍歷getValue()方法來取值:
foreach(getValues()as$value){
echo$value;
//使用變量也是好的
$values=getValues();
foreach($valuesas$value){
echo$value;
}
但這不是唯一的不同!
一個(gè)生成器運(yùn)行你寫使用循環(huán)來迭代一維數(shù)組的代碼,而不需要在內(nèi)存中創(chuàng)建是一個(gè)數(shù)組,這可能會(huì)導(dǎo)致你超出內(nèi)存限制。
在下面的例子里我們創(chuàng)建一個(gè)有800,000元素的數(shù)字同時(shí)從getValues()方法中返回他,同時(shí)在此期間,我們將使用函數(shù)memory_get_usage()來獲取分配給次腳本的內(nèi)存,我們將會(huì)每增加200,000個(gè)元素來獲取一下內(nèi)存使用量,這意味著我們將會(huì)提出四個(gè)檢查點(diǎn):
php
functiongetValues(){
$valuesArray=[];
//獲取初始內(nèi)存使用量
echoround(memory_get_usage()/1024/1024,2).'MB'.PHP_EOL;
for($i=1;$i800000;$i++){
$valuesArray[]=$i;
//為了讓我們能進(jìn)行分析,所以我們測(cè)量一下內(nèi)存使用量
if(($i%200000)==0){
//來MB為單位獲取內(nèi)存使用量
echoround(memory_get_usage()/1024/1024,2).'MB'.PHP_EOL;
return$valuesArray;
$myValues=getValues();//一旦我們調(diào)用函數(shù)將會(huì)在這里創(chuàng)建數(shù)組
foreach($myValuesas$value){}
前面例子發(fā)生的情況是這個(gè)腳本的內(nèi)存消耗和輸出:
0.34MB
8.35MB
16.35MB
32.35MB
這意味著我們的幾行腳本消耗了超過30MB的內(nèi)存,每次你你添加一個(gè)元素到$valuesArray數(shù)組中,都會(huì)增加他在內(nèi)存中的大小。
讓我們使用yield同樣的例子:
php
functiongetValues(){
//獲取內(nèi)存使用數(shù)據(jù)
echoround(memory_get_usage()/1024/1024,2).'MB'.PHP_EOL;
for($i=1;$i800000;$i++){
yield$i;
//做性能分析,因此可測(cè)量?jī)?nèi)存使用率
if(($i%200000)==0){
//內(nèi)存使用以MB為單位
echoround(memory_get_usage()/1024/1024,2).'MB'.PHP_EOL;
$myValues=getValues();//在循環(huán)之前都不會(huì)有動(dòng)作
foreach($myValuesas$value){}//開始生成數(shù)據(jù)
這個(gè)腳本的輸出令人驚訝:
0.34MB
0.34MB
0.34MB
0.34MB
這不意味著你從return表達(dá)式遷移到y(tǒng)ield,但如果你在應(yīng)用中創(chuàng)建會(huì)導(dǎo)致服務(wù)器上內(nèi)存出問題的巨大數(shù)組,則yield更加適合你的情況。
4.什么是yield選項(xiàng)
這里有很多yield的選項(xiàng),我將強(qiáng)調(diào)他們中的幾個(gè):
a.使用yield,你也可以使用return。
functiongetValues(){
yield'value';
return'returnValue';
$values=getValues();
foreach($valuesas$value){}
echo$values-getReturn();//'returnValue'
b.返回鍵值對(duì):
functiongetValues(){
yield'key'='value';
$values=getValues();
foreach($valuesas$key=$value){
echo$key.'='.$value;
}
5.生成器
1使用生成器來生成一個(gè)1到100的數(shù)組
functionmy_range($start,$limit){
for($i=$start;$i=$limit;$i++){
yield$i;
}
2打印出來,看下返回究竟是什么
$arr=my_range(1,100);
var_dump($arr);
結(jié)果是:
object(Generator)#1(0){
}
可見是一個(gè)對(duì)象,是一個(gè)生成器對(duì)象,既然是對(duì)象那么也就是可以用foreach來遍歷
3遍歷生成器
foreach($arras$num){
echo$num.PHP_EOL;
}
看到可以完整遍歷出來,那么與那樣實(shí)現(xiàn)的不同地方,意義在哪里呢。重點(diǎn)來了。
4兩者內(nèi)存占用比較
上面已經(jīng)測(cè)試過使用數(shù)組的方式,隨著范圍的增大占用的內(nèi)存劇增,很快就超過了PHP的內(nèi)存上限。
那么使用生成器占用了多少內(nèi)存呢,來看看就知道了。
$start=memory_get_usage();
$arr=my_range(1,100);
$end=memory_get_usage();
echo$end-$start.'bytes'.PHP_EOL;
可以看到只占用了576bytes,當(dāng)然每個(gè)人測(cè)試的可能都會(huì)有點(diǎn)不同,環(huán)境不同,但是這不是重點(diǎn)。
我們?cè)賴L試增加數(shù)字范圍,可以看到數(shù)字范圍并沒有影響到內(nèi)存占用,也就是可以輕松的遍歷超大數(shù)字。
$start=memory_get_usage();
$arr=my_range(1,100000000);
$end=memory_get_usage();
echo$end-$start.'bytes'.PHP_EOL;
foreach($arras$num){
echo$num.PHP_EOL;
}
這下我們就可以遍歷1到10000000的數(shù)字了,不相信內(nèi)存占用那么低的小伙伴,可以打開任務(wù)管理器毫無波瀾,即時(shí)再上調(diào)數(shù)字范圍。
5、生成器遍歷原理
生成器既
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 行政制度管理規(guī)范
- 重要制度制定不規(guī)范
- 規(guī)范社保制度
- 設(shè)備使用規(guī)范制度
- 規(guī)范交通秩序工作制度
- 科技公司日常規(guī)范制度
- 藥品盤存制度規(guī)范
- 規(guī)范學(xué)生作業(yè)制度
- 銀行、人保系統(tǒng)職工基本養(yǎng)老保險(xiǎn)制度改革宣傳提綱
- 2025年人工智能筆試題及答案
- 耳石癥教學(xué)課件
- 《潮漲潮落》課件
- 光儲(chǔ)充項(xiàng)目收益Excel自動(dòng)測(cè)算表
- 鞍鋼集團(tuán)電子招投標(biāo)交易平臺(tái)簡(jiǎn)明操作手冊(cè)
- 非標(biāo)設(shè)備項(xiàng)目管理制度
- 房屋劃撥協(xié)議書范本
- 門店運(yùn)營年終總結(jié)匯報(bào)
- 2025年中國流體動(dòng)壓軸承市場(chǎng)調(diào)查研究報(bào)告
- 醫(yī)療器械銷售年終工作總結(jié)
- 快遞行業(yè)運(yùn)營部年度工作總結(jié)
- 《蘇教版六年級(jí)》數(shù)學(xué)上冊(cè)期末總復(fù)習(xí)課件
評(píng)論
0/150
提交評(píng)論