PHP
性能優化:
整體介紹:
1、規範說明
性能是網站運行是否良好的關鍵因素,
網站的性能與效率影響着公司的運營成本及長遠發展,編寫出高質高效的代碼是咱們每一個開發人員必備的素質,
也是咱們良好的職業素養。
2、影響性能的因素
A
、
商業需求
1.
需求合理性
2.
需求與系統的整合
3.
需求所帶來的商業利益是否與需求開發的成本成正比
4.
需求所帶來的風險
B
、 Web
服務器
1.
併發處理能力
2.
高負載的能力
3.
負載均衡的能力
4.
動態內容與靜態內容的處理能力
5. Web
服務器部署
C
、DataBase
服務器
1.
併發訪問
2.
數據庫服務器的部署
3.
數據庫的 shema
架構與的表設計是否合理
4.
數據檢索
D
、
操做系統
E
、
客戶端請求
F
、
程序/
語言
3、分析性能的指標
1.
程序的運行時間microtime()
2.
程序的運行所消耗的內存memory_get_usage()
3.
單位時間內的並行處理
4.
磁盤 IO
的處理
4、優化性能的目標
快速、併發、資源消耗低(內存、磁盤 IO
、CPU
負載)
5、優化性能的原則
1.
服務器配配置最優化
2.
服務器部署合理化
3.
商業需求合理並與產出的商業價值成正比
4.
架構可用、可維護、可擴展
5.
程序的正確性、簡單性、邏輯的合理性。
6.
不斷的分析性能的的瓶頸
7.
不斷的重構已有的代碼
8.
優化的優先級:program->database->web sersver->os->client
代碼優化:
(1
)鏈接字符使用 ,
代替 . echo ‘string1’,$a,’string2’,$b;
(2
)循環以前先取出最大值,而不是在循環裏面取值
$max = count($array);
for ($i=0;$i<$max;$i++) {
echo $i;
}
(3
)使用 static
靜態方法比普通方法快4
倍,static
表示的屬性只初始化一次 DataInterface::getUserIds($uid);
(4
)
在PHP
中的執行速率從快到慢爲:echo(), print(), print_r()
,
echo
是PHP語句, print和print_r是函數,語句沒有返回值,函數能夠有返回值(即使沒有用)
(5
)使用unset
釋放給定的變量
(6
)includes
和requires
包含文件使用完整路徑
(7
)使用strncasecmp, strpbrk
和 stripos
代替 regex
(8
)使用switch
代替if else
語句
(9
)抑制錯誤符@
性能很低,
報錯函數
(10
)任什麼時候間記住關閉不須要的數據庫鏈接
(11
)$row['id']
比 $row[id]
性能快7
倍
(12
)增長一個全局變量比增長一個局部變量慢2
倍
(13
)使用單引號而不是雙引號引用字符
(14
)使用HTML
比PHP
腳本快2-20
倍
(15
)使用PHP
緩存可加速性能25%-100%
(16
)$++
比++$i
慢
(17
)不要過分使用OOP
,適度而止
(18
)儘可能使用PHP
內置函數
·
變量
1
、
變量長度小,
注意變量大小是節約內存的最有效手段,對於來自用戶表單、數據庫和文件緩存的數據都須要控制變量的大小。
由於cpu
要處理的數據是來源於內存,名字越長查詢所須要的時間就越多
2
、unset()
函數註銷不須要的變量是一種良好的習慣,將一些不須要的變量當即註銷可提升內存的使用率。
3
、
儘可能不要複製變量,不然就會帶來1
倍的內存消耗,即便複製變量也應該要當即註銷原有變量。
4
、
變量類型,
初始化變量請注意其變量類型,一個變量在執行過程當中最好只有一種類型狀態。對於數組變量,請初始化聲明,以下: $a = array();
5
、
臨時變量,
是處理業務邏輯的臨時存儲,這些都是須要消耗內存的。若是臨時變量使用結束請當即註銷,特別是在一些過程式代碼的執行流程中,對於一些函數,若是業務很是複雜,一樣須要當即註銷臨時變量
6
、
靜態變量,
對於一些須要由複雜業務產生的變量,若是在程序的執行過程當中屢次產生並使用,可考慮使用靜態變量,減小程序的cpu
執行次數
7
、
變量的性能:局部變量>
全局變量>
類屬性>
未定義的變量。
·
循環
1
、
儘可能減小循環的次數。
2
、
儘可能減小循環的潛逃的層次,不要超過三層。
3
、
避免在循環內有過多的業務邏輯。
4
、
不要循環包含文件
5
、
不要循環執行數據庫操做。
6
、
優先使用foreach,
它比for/while
效率高
7
不要把 count/strlen/sizeof
放到 for
循環的條件語句中For($i=0,$count=count($array);$i<$count;$i++){}
不要使用for($i=0;$i<count($array);$i++){};
8
、 for($i=$total;$i>0;$i
–){}
性能好於for($i=0;$i<$total;$
–){}
9
、
保持循環體內的業務邏輯清晰
·
函數
1
、
函數職責清晰,一個函數只幹一件事,不要雜揉過多的業務邏輯
2
、
函數代碼體不要超過20
行,反之,考慮拆分。
3
、
優先使用php
內置函數,內置函數的參數獲取,經過zend_parse_parameters
方法來實現,對於數組、字符串等參數,zend
實現的是淺拷貝,所以這個效率是很高的。能夠這樣說,對於php
內置函數,其效率和相應c
函數幾乎相同,惟一多了一次轉發調用。
4
、
常量與函數同時能幹一件事,優先使用常量。
· phpversion()< PHP_VERSION
· get_class()< __CLASS__
· is_null()< NULL ===
6
、 $_SERVER[REQUEST_TIME]
替換time();
7
、
字符串替換strtr()->str_replace()->preg_replace()->epreg();
8
、
發揮trim
最大功效,替換substr
。$filepath=trim($filename,
’/
’).
’/
’;
9
、Isset/empty
雖然兩個函數功能有所差別,但在一樣的狀況下推薦使用 empty()
10
、isfile/file_exist
兩個函數的功能有所不一樣,file_exist
既可判斷文件是否存在,也能夠判斷目錄是否存在,在一樣的狀況下推薦使用is_file
11
、php
中的僞函數
Isset empty unset eval
經過上面的介紹能夠看出,僞函數因爲被直接翻譯成指令來執行,和普通函數相比少了一次函數調用所帶來的開銷,所以性能會更好一些。
mt_rand
平均速度比 libc
提供的 rand()
快四倍。
·
文件
1
、
減小文件包含數,減小磁盤 IO
2
、
使用完整路徑,或者容易轉換的相對路徑。避免在 include_path
查找
3
、
文件的代碼行數不要超過 2000
行
4
、Require_once/include_once
效率低於 require/include,
須要額外的去查看系統是否已經調用過這個文件.
由於它們在一個opcode
緩存下的調用很是慢
5
、程序執行文件用 requie/require_once,
緩存文件用include/include_once
。Include
效率好於 require
6
、優化 spl
中的文件自動加載機制,可參靠yii
7
、類庫文件加載,是否考慮類是否已經實例化,可考慮採用設計模式之單例模式
8
、文件讀寫的併發性
面向對象
1
、
控制實例的建立的數量
2
、
優先使用常量、類常量
3
、
優先例用靜態變量,靜態屬性
4
、
類的結構合理
5
、
面象接口編程
6
、
封裝變化點
7
、
依賴於抽象,不依賴於細節
8
、
優先使用靜態成員
9
、
類的接口清晰穩定,類的職責單一,類與類的通訊合理
10
、
使用常量的好處
編譯時解析,沒有額外開銷
雜湊表更小,因此內部查找更快
類常量僅存在於特定「命名空間」,因此雜湊名更短
代碼更乾淨,使除錯更方便
字符串
1
、
用單引號替代雙引號引用字符串;避免檢索字符串中的變量
運算
1
、
用 i+=1
代替i=i+1
。符合c/c++
的習慣,效率還高
4
、 if/else
與_&&,
單條語句判斷請選擇&&
的形式, &&
的效率高於if/else
,以下 :
if ($a == 1) {
$b = 2;
}
可選擇爲($a == 1) && $b = 2;
緩存
1
、
使用php
加速器,緩衝opcode
2
、
例用memcache/nosql
3
、
使用內存數據庫、
4
、
使用文件緩存
5
、
緩衝功能
其它
1
、
少用@
符號,嚴重影響性能
2
、
適時關閉遠程資源鏈接如數據庫,ftp
、socket
等,適時的清理這些資源
B
、
數據庫優化
1
、
合理的商業需情
2
、
數據庫 schema
架構優化
3
、
垂直與水平分庫分表
4
、
索引優化,查詢優化
5
、
第三方開源檢索工具(sphinx)
6
、
主從數據庫服務器的使用。
C
、 Web
服器優化(暫未整理,
有相應的 Web
服務器優化手冊)
D
、
操做系統優化(
暫未整理,
有相應的 OS
優化手冊)
E
、
前端優化
1
、合理的 html
結構
2
、合理 html
與css
的同時,考慮 Css
設計合理,減小 http
請求
3
、合理 html
與java script
的同時,考慮拆分是否合理,減小 http
請求
4
、優化 java script
代碼,讓用戶有良好的體驗
5
、根據 http
協議,優化高併發請求
1
.
一個功能能夠用內置函數完成,儘可能使用它而不是本身編寫php
函數。
2
.
若是某個功能對性能要求很高,能夠考慮用擴展來實現。
3
. Php
函數調用開銷較大,所以不要過度封裝。有些功能,若是須要調用的次數不少自己又只用1
、2
行代碼就行實現的,建議就不要封裝調用了。
4
.
不要過度迷戀各類設計模式,如上一條描述,過度的封裝會帶來性能的降低。須要考慮二者的權衡。Php
有本身的特色,切不可東施效顰,過度效仿java
的模式。
5
.
函數不宜嵌套過深,遞歸使用要謹慎。
6
.
僞函數性能很高,同等功能實現下優先考慮。好比用isset
代替array_key_exists
7
.
函數返回引用沒有太大意義,也起不到實際做用,建議不予考慮。
8
.
類成員方法效率不比普通函數低,所以不用擔憂性能損耗。建議多考慮靜態方法,可讀性及安全性都更好。
9
.
如不是特殊須要,參數傳遞都建議使用傳值而不是傳引用。固然,若是參數是很大的數組且須要修改時能夠考慮引用傳遞。
|