為您提供行業(yè)資訊、活動(dòng)公告、產(chǎn)品發(fā)布,匯聚最前沿流行的云計算技術(shù)
php性能怎么優(yōu)化?性能是網(wǎng)站運行是否良好的關(guān)鍵因素, 網(wǎng)站的性能與效率影響著(zhù)公司的運營(yíng)成本及長(cháng)遠發(fā)展,編寫(xiě)出高質(zhì)高效的代碼是我們每個(gè)開(kāi)發(fā)人員必備的素質(zhì),也是我們良好的職業(yè)素養。
什么情況之下,會(huì )遇到PHP性能問(wèn)題?
1:PHP語(yǔ)法使用不恰當。
2:使用PHP語(yǔ)言做了它不擅長(cháng)的事情。
3:使用PHP語(yǔ)言連接的服務(wù)不給力。
4:PHP自身的短板(PHP自身做不了的事情)。
5:我們也不知道的問(wèn)題?(去探索、分析找到解決辦法,提升開(kāi)發(fā)境界)。
對線(xiàn)上站點(diǎn)做壓力測試的時(shí)候,我們一定要將請求數和并發(fā)數,特別是并發(fā)數要設置的比較低,我們不能對線(xiàn)上的網(wǎng)站造成壓力問(wèn)題,不管是自己的還是別人的。
PHP性能問(wèn)題一般不會(huì )超過(guò)占整個(gè)項目性能的50%,一般在30%~40%。
PHP性能問(wèn)題的解決方向,三個(gè)層級
1:PHP語(yǔ)言級的性能優(yōu)化,指的是PHP語(yǔ)法基本功能,這部分優(yōu)化比較簡(jiǎn)單易見(jiàn)、快速可行,比較快速看到效果。
a:少寫(xiě)PHP的代碼,多用PHP自身能力解決問(wèn)題。
性能問(wèn)題
自寫(xiě)代碼冗余較多,可讀性不佳,并且性能低,如代碼很長(cháng)很長(cháng)…PHP代碼越長(cháng)PHP的執行效率越慢。
為什么性能低?
PHP代碼需要解析編譯為C語(yǔ)言,底層C語(yǔ)言又要編譯成匯編語(yǔ)言機器語(yǔ)言才能執行,這個(gè)過(guò)程在每次請求過(guò)來(lái)之后都要處理一遍,所以開(kāi)銷(xiāo)很大(項目變大的話(huà)…)。
解決方法:
多使用PHP內置的變量、常量、函數。我們用PHP代碼實(shí)現的功能和使用PHP內置的函數實(shí)現的同樣功能差別是有的。
b:PHP內置函數的性能優(yōu)劣。
情況描述:
PHP內置函數之間依然存在快慢差別;少用PHP魔術(shù)方法;
建議:
多去了解PHP內置函數的執行實(shí)現復雜度。
測試方法:比較效率測試,如用microtime()函數,取差值,精確到毫秒級別;Linux的time命令可以查看開(kāi)銷(xiāo)。
c:產(chǎn)生額外開(kāi)銷(xiāo)的錯誤抑制符號“@”
最好別用(不管是性能優(yōu)化和項目的健壯性等方面)。
@的邏輯是在代碼前和代碼結束后增加了Opcode,Opcode的作用就是忽略報錯,其實(shí)就是相當于增加了error_reporting設置,等級報錯為忽略(vld擴展可以查看被隱藏的Opcode);
d:合理使用內存。
情況描述:
PHP有內存回收機制保底,但是也小心使用內存;
建議:
利用unset()及時(shí)釋放不使用的內存,比如一些數據庫多余字段(注意:unset()有時(shí)會(huì )出現注銷(xiāo)不掉的情況)
e:盡量少用正則表達式。
情況描述:
正則表達式的開(kāi)銷(xiāo)大,使用起來(lái)簡(jiǎn)單,但是性能低因為,正則表達式需要回溯;正則表達式越長(cháng),回溯的開(kāi)銷(xiāo)越大,優(yōu)化正則表達式是需要技術(shù)水平的,正則技術(shù)不達標,不要亂用正則。
f:避免在循環(huán)內做運算。
情況描述:
循環(huán)內的計算式將被重復計算(我們在for循環(huán)或者while循環(huán),會(huì )有重復計算,影響性能問(wèn)題)。
舉例:
錯誤用法:
$str = “hello world”;
for($i = 0; $i < strlen($str); $i ++){ …}
正確用法:
$str = “hello world”;
$strlen = strlen($str);
for($i = 0; $i < $strlen; $i++){…}
g:減少計算密集型業(yè)務(wù)
情況描述:
PHP不適合密集型(大數據量)運算的場(chǎng)景。
為什么?
PHP的語(yǔ)言特性決定PHP不適合做大數據量運算,PHP語(yǔ)言由C寫(xiě)的,PHP處于C基礎之上,PHP的所有運算處理流程需要轉化為C語(yǔ)言,PHP和C想比性能肯定輸了,并且
PHP語(yǔ)言還有一些環(huán)境問(wèn)題、語(yǔ)言特性,相比于C而言的開(kāi)銷(xiāo)要大很多的。PHP一段很長(cháng)的代碼,可能C很短就實(shí)現了…
PHP適合場(chǎng)景:
適合銜接WebServer與后端服務(wù),WebServer來(lái)了請求交給PHP,PHP做一些校驗、一些初始化數據處理,將請求轉發(fā)交給后端,等待后臺響應,后端可能是緩存、DB等其他業(yè)務(wù),
后端響應之后,PHP再作為紐帶,將信息傳遞給WebServer,這是PHP擅長(cháng)的。PHP也擅長(cháng)做UI呈現,也就是配合模板引擎做模板輸出,其實(shí)就是一些字符串文本處理。
h:務(wù)必使用帶引號字符串做鍵值(數組的Key字段)。
情況描述
PHP會(huì )將沒(méi)有使用引號的鍵值當做常量,產(chǎn)生查找常量的開(kāi)銷(xiāo),如果查找到了常量有這個(gè)字符串,那么就把常量作為這個(gè)值了。
建議:
嚴格使用引號作為鍵值,單引號即可。
2:PHP周邊的性能優(yōu)化:(PHP前面有WebServer,后面有數據庫)
3:PHP語(yǔ)言自身的分析、優(yōu)化(底層C級別的優(yōu)化)
補充:
1:盡量靜態(tài)化:
如果一個(gè)方法能被靜態(tài),那就聲明它為靜態(tài)的,速度可提高1/4,甚至我測試的時(shí)候,這個(gè)提高了近三倍。
當然了,這個(gè)測試方法需要在十萬(wàn)級以上次執行,效果才明顯。
其實(shí)靜態(tài)方法和非靜態(tài)方法的效率主要區別在內存:靜態(tài)方法在程序開(kāi)始時(shí)生成內存,實(shí)例方法在程序運行中生成內存,所以靜態(tài)方法可以直接調用,實(shí)例方法要先成生實(shí)例,通過(guò)實(shí)例調用方法,靜態(tài)速度很快,但是多了會(huì )占內存。
任何語(yǔ)言都是對內存和磁盤(pán)的操作,至于是否面向對象,只是軟件層的問(wèn)題,底層都是一樣的,只是實(shí)現方法不同。靜態(tài)內存是連續的,因為是在程序開(kāi)始時(shí)就生成了,而實(shí)例申請的是離散的空間,所以當然沒(méi)有靜態(tài)方法快。
靜態(tài)方法始終調用同一塊內存,其缺點(diǎn)就是不能自動(dòng)進(jìn)行銷(xiāo)毀,而是實(shí)例化可以銷(xiāo)毀。
2.銷(xiāo)毀變量去釋放內存,特別是大的數組;
數組和對象在php特別占內存的,這個(gè)由于php的底層的zend引擎引起的,
一般來(lái)說(shuō),PHP數組的內存利用率只有 1/10, 也就是說(shuō),一個(gè)在C語(yǔ)言里面100M 內存的數組,在PHP里面就要1G。
特別是在PHP作為后臺服務(wù)器的系統中,經(jīng)常會(huì )出現內存耗費太大的問(wèn)題。
以下是我在其他博文收集的php性能優(yōu)化方法:
1、如果能將類(lèi)的方法定義成static,就盡量定義成static,它的速度會(huì )提升將近4倍。
2、$row[’id’] 的速度是$row[id]的7倍。
3、注銷(xiāo)那些不用的變量尤其是大數組,以便釋放內存。
4、盡量避免使用__get,__set,__autoload。
5、require_once()代價(jià)昂貴。
6、include文件時(shí)盡量使用絕對路徑,因為它避免了PHP去include_path里查找文件的速度,解析操作系統路徑所需的時(shí)間會(huì )更少。
7、如果你想知道腳本開(kāi)始執行(譯注:即服務(wù)器端收到客戶(hù)端請求)的時(shí)刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()
8、函數代替正則表達式完成相同功能。
9、str_replace函數比preg_replace函數快,但strtr函數的效率是str_replace函數的四倍。
10、如果一個(gè)字符串替換函數,可接受數組或字符作為參數,并且參數長(cháng)度不太長(cháng),那么可以考慮額外寫(xiě)一段替換代碼,使得每次傳遞參數是一個(gè)字符,而不是只寫(xiě)一行代碼接受數組作為查詢(xún)和替換的參數。
11、使用選擇分支語(yǔ)句(譯注:即switch case)好于使用多個(gè)if,else if語(yǔ)句。
12、用@屏蔽錯誤消息的做法非常低效,極其低效。
13、打開(kāi)apache的mod_deflate模塊,可以提高網(wǎng)頁(yè)的瀏覽速度。
14、數據庫連接當使用完畢時(shí)應關(guān)掉,不要用長(cháng)連接。
15、在方法中遞增局部變量,速度是最快的。幾乎與在函數中調用局部變量的速度相當。遞增一個(gè)全局變量要比遞增一個(gè)局部變量慢2倍。遞增一個(gè)對象屬性(如:$this->prop++)要比遞增一個(gè)局部變量慢3倍。遞增一個(gè)未預定義的局部變量要比遞增一個(gè)預定義的局部變量慢9至10倍。
16、僅定義一個(gè)局部變量而沒(méi)在函數中調用它,同樣會(huì )減慢速度(其程度相當于遞增一個(gè)局部變量)。PHP大概會(huì )檢查看是否存在全局變量。
17、方法調用看來(lái)與類(lèi)中定義的方法的數量無(wú)關(guān),因為我(在測試方法之前和之后都)添加了10個(gè)方法,但性能上沒(méi)有變化。
18、派生類(lèi)中的方法運行起來(lái)要快于在基類(lèi)中定義的同樣的方法。
19、調用帶有一個(gè)參數的空函數,其花費的時(shí)間相當于執行7至8次的局部變量遞增操作。類(lèi)似的方法調用所花費的時(shí)間接近于15次的局部變量遞增操作。
20、Apache解析一個(gè)PHP腳本的時(shí)間要比解析一個(gè)靜態(tài)HTML頁(yè)面慢2至10倍。盡量多用靜態(tài)HTML頁(yè)面,少用腳本。
21、除非腳本可以緩存,否則每次調用時(shí)都會(huì )重新編譯一次。引入一套PHP緩存機制通??梢蕴嵘?5%至100%的性能,以免除編譯開(kāi)銷(xiāo)。
22、盡量做緩存,可使用memcached。memcached是一款高性能的內存對象緩存系統,可用來(lái)加速動(dòng)態(tài)Web應用程序,減輕數據庫負載。對運算碼 (OP code)的緩存很有用,使得腳本不必為每個(gè)請求做重新編譯。
23、當操作字符串并需要檢驗其長(cháng)度是否滿(mǎn)足某種要求時(shí),你想當然地會(huì )使用strlen()函數。此函數執行起來(lái)相當快,因為它不做任何計算,只返回在zval 結構(C的內置數據結構,用于存儲PHP變量)中存儲的已知字符串長(cháng)度。但是,由于strlen()是函數,多多少少會(huì )有些慢,因為函數調用會(huì )經(jīng)過(guò)諸多步驟,如字母小寫(xiě)化(譯注:指函數名小寫(xiě)化,PHP不區分函數名大小寫(xiě))、哈希查找,會(huì )跟隨被調用的函數一起執行。在某些情況下,你可以使用isset() 技巧加速執行你的代碼。
24、當執行變量$i的遞增或遞減時(shí),$i++會(huì )比++$i慢一些。這種差異是PHP特有的,并不適用于其他語(yǔ)言,所以請不要修改你的C或Java代碼并指望它們能立即變快,沒(méi)用的。++$i更快是因為它只需要3條指令(opcodes),$i++則需要4條指令。后置遞增實(shí)際上會(huì )產(chǎn)生一個(gè)臨時(shí)變量,這個(gè)臨時(shí)變量隨后被遞增。而前置遞增直接在原值上遞增。這是最優(yōu)化處理的一種,正如Zend的php優(yōu)化器所作的那樣。牢記這個(gè)優(yōu)化處理不失為一個(gè)好主意,因為并不是所有的指令優(yōu)化器都會(huì )做同樣的優(yōu)化處理,并且存在大量沒(méi)有裝配指令優(yōu)化器的互聯(lián)網(wǎng)服務(wù)提供商(ISPs)和服務(wù)器。
25、并不是事必面向對象(OOP),面向對象往往開(kāi)銷(xiāo)很大,每個(gè)方法和對象調用都會(huì )消耗很多內存。
26、并非要用類(lèi)實(shí)現所有的數據結構,數組也很有用。
27、盡量采用大量的PHP內置函數。
28、如果在代碼中存在大量耗時(shí)的函數,你可以考慮用C擴展的方式實(shí)現它們。
29、評估檢驗(profile)你的代碼。檢驗器會(huì )告訴你,代碼的哪些部分消耗了多少時(shí)間。Xdebug調試器包含了檢驗程序,評估檢驗總體上可以顯示出代碼的瓶頸。
30、mod_zip可作為Apache模塊,用來(lái)即時(shí)壓縮你的數據,并可讓數據傳輸量降低80%。
31、在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情況下,盡量用file_get_contents,因為他的效率高得多!但是要注意file_get_contents在打開(kāi)一個(gè)URL文件時(shí)候的PHP版本問(wèn)題;
32、盡量的少進(jìn)行文件操作,雖然PHP的文件操作效率也不低的;
33、優(yōu)化Select SQL語(yǔ)句,在可能的情況下盡量少的進(jìn)行Insert、Update操作(在update上,我被惡批過(guò));
34、循環(huán)內部不要聲明變量,尤其是大變量:對象(這好像不只是PHP里面要注意的問(wèn)題吧?);
35、多維數組盡量不要循環(huán)嵌套賦值;
36、在可以用PHP內部字符串操作函數的情況下,不要用正則表達式;
37、foreach效率更高,盡量用foreach代替while和for循環(huán);
38、用單引號替代雙引號引用字符串;
39、“用i+=1代替i=i+1。符合c/c++的習慣,效率還高”;
40、對global變量,應該用完就unset()掉;
更多資訊:更多資訊
本站發(fā)布的【php性能怎么優(yōu)化?php性能優(yōu)化及安全策略】?jì)热荩▓D片、視頻和文字)以原創(chuàng )、轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng)
如果涉及侵權請盡快告知,我們將會(huì )在第一時(shí)間立刻刪除涉嫌侵權內容,本站原創(chuàng )內容未經(jīng)允許不得轉載,或轉載時(shí)需注明出處。
Copyright ? 2009-2024 56dr.com. All Rights Reserved. 特網(wǎng)科技 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站