這篇文章介紹的內容是關於php中一些提高效能的技巧 ,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
php中一些提高效能的技巧
tags:php效能 提高效能 php中的@ php的靜態
引言:php作為一種指令碼語言,本身的效能上肯定是不如c++或者java的。擁有簡單易學的特性的同時,效能提升的空間也並不是沒有。養成一些好的編程習慣,也許可以讓你的php代碼效能得到可見的提升。
一、消除不必要的錯誤提示
有很多朋友編程的時候遇到notice和warning這類的錯誤,如果不影響正常的邏輯就不去處理了,類似下面這種
<?php //想在迴圈中拼接字串,卻不初始化字串直接使用 .= $list = array( 1=>'hello', 2=>'world' //... ); foreach($list as $key=>$val){ $str .= $val; } // Notice: Undefined variable: str in D:\11\index.php /*********************************************************/ //不注意的數組下標越界或key不存在 $List_1 = array('1','2'); echo $List_1[3]; //Notice: Undefined offset: 3 in D:\11\index.php on line 13 /*********************************************************/ //使用已經過時的函數 比如使用函數mysql_escape_string()會有如下提示 //Deprecated: mysql_escape_string(): This function is deprecated; use mysql_real_escape_string() instead. in D:\readCode\xhprofshoujikanbingcom\cgi\xhprof.php on line 51 /*********************************************************/ //靜態調用非靜態方法 報E_STRICTclass Cl_a{ function a(){ echo 'A類的a方法'; }}class Cl_B{ static function b(){ echo 'B類的b方法'; }}function test_1(){ $a = new Cl_a(); $a::a();}function test_2(){ $b = new Cl_b(); $b::b();}test_1();test_2(); //Strict standards: Non-static method Cl_a::a() should not be called statically in D:\11\index.php on line 15?>
這種情況會導致效能的下降,凡是能引起警告(warning or E_STRICT )或者提示(notice)的代碼都會走php的異常流程,記錄異常日誌(涉及到檔案I/O)。效能可能會降低50%左右。
二、使用靜態變數和方法
測試結果如下
<?phpclass Cl_a{ public $a=1; function a(){ $this->a++; }}class Cl_b{ public static $a = 1; static function b(){ self::$a++; }}function test_1(){ $a = new Cl_a(); for($i=0;$i<1000;$i++){ $c=$a->a+1;//外部調用 $a->a();//內部調用 } echo $a->a;}function test_2(){ $b = new Cl_b(); for($i=0;$i<1000;$i++){ $c=$b::$a+1;//外部調用 $b::b();//內部調用 } echo $b::$a;}test_1(); //51012微秒test_2(); //49039微秒?>
三、盡量不適用@符號
說實話我沒見到過必須使用@符號的地方
<?phpclass Cl_a{ public $a=1; function a(){ $b =1; }}function test_1(){ @$a = new Cl_a(); for($i=0;$i<1000;$i++){ @$a->a();//內部調用 } echo $a->a;}function test_2(){ $a = new Cl_a(); for($i=0;$i<1000;$i++){ $a->a();//內部調用 } echo $a->a;}@test_1(); //51,133test_2(); //48,381?>
四、使用php內建的變數來代替一些函數。
某些時候也可以用$_SERVER[‘REQUEST_TIME’]替換time()。、
這個效能的提示我測試出的結果讓我都有些不能相信
<?phpfunction test_1(){ for($i=0;$i<1000;$i++){ $a = php_uname('s'); $b = phpversion(); $c = php_sapi_name(); } echo $a,$b,$c;}function test_2(){ for($i=0;$i<1000;$i++){ $a = PHP_OS; $b = PHP_VERSION; $c = PHP_SAPI; } echo $a,$b,$c;}test_1(); //132,015 test_2(); //340 驚不驚喜意不意外$is_win = DIRECTORY_SEPARATOR == '//'; //可以用來判斷是不是windows系統 速度很快?>
五、注意不要把一些不必要的耗時代碼寫到迴圈中
例如,cuont函數不要寫在for迴圈的條件中,不要在迴圈中聲明不必要的變數等。
<?phpfunction test_1(){ $a = array( 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, ); for($i=0;$i<count($a);$i++){ }}function test_2(){ $a = array( 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, 1,2,3,4,5,6,7,8,9,0, ); $count = count($a); for($i=0;$i<$count;$i++){ }}test_1();//3,602test_2();//223?>
六、盡量用php內建的函數替換正則
這個網上有很多對比的,我就不再重新寫一遍了;
直接給一下常用的三個函數效能對比:str_replace > strtr > preg_replace
七、包含檔案有技巧
包含檔案的時候,如果能確定不會重複包含,盡量使用include,require不要用include_once和require_once,而且包含錯誤(一般you 函數和變數被覆蓋)通常是可以被測試出來的。
測試結果如下:
<?phpfunction test_1(){ $a ='11'; for($i=0;$i<1000;$i++){ include_once 'a.php'; }}function test_2(){ $a ='11'; for($i=0;$i<1000;$i++){ include 'a.php'; }}test_1();//1,477test_2();//152,704?>
八、可以用全等號代替雙等
這個相信有很多人都知道,因為雙等號是會有類型轉換的。
測試結果如下:
<?phpfunction test_1(){ $a ='11'; for($i=0;$i<1000;$i++){ if($a=='11'){ echo 1; } }}function test_2(){ $a ='11'; for($i=0;$i<1000;$i++){ if($a==='11'){ echo 1; } }}test_1();//耗時501微秒test_2();//耗時434微秒?>
九、多維陣列賦值可以使用引用來提高效能
多維陣列越複雜,引用帶來的效能提高越大,引用可以減少數組元素的雜湊尋找次數。
<?phpfunction test_1(){ $a['b']['c'] = array(); $a['b']['d'] = array(); for($j=0;$j<1000;$j++){ for ($i = 0; $i < 5; ++$i){ $a['b']['c'][$i] = $i; } }}function test_2(){ $a['b']['c'] = array(); $a['b']['d'] = array(); $ref =& $a['b']['c']; for($j=0;$j<1000;$j++){ for ($i = 0; $i < 5; ++$i){ $ref[$i] = $i; } }}test_1();//1270test_2();//1015//多維陣列越複雜,引用帶來的效能提高越大,引用可以減少數組元素的雜湊尋找?>
十、大的數組或資料如果使用完畢,及時unset掉
這個就不用過多解釋了,節省記憶體。
十一、不做無意義的封裝
如果不能實現特別好的設計,解耦,複用效果可以不封裝簡單方法
因為每次調用方法都會開闢一個新的記憶體地區,傳值的時候對資料的引用也會增加。
十二、為代碼和資料做緩衝
這個資料緩衝就不用說了,可能有部分朋友不知道代碼緩衝,代碼緩衝節省代碼已耗用時間的遠離:php是解釋型語言,和編譯型語言的區別如下:
編譯型語言:編程完成後,通過預先處理->編譯->彙編->連結後變成可執行程式(電腦直接啟動並執行二進位檔案),以後每次運行都直接運行這個可執行性檔案。
解釋型語言:具體的過程這裡也說不清楚,可以理解為,解釋型語言每次啟動並執行時候都相當於進行了上面編譯型語言編譯的過程(其實還不太一樣)產生可執行檔檔案。
opcache就是把解釋後的檔案存入了記憶體,每次啟動並執行時候就不用經過解釋的過程,可以提高20%-100%的效能(資料來自網路,但是原理上肯定是能提升效能的,如果代碼經常迭代的話慎用)。
十三、用單引號替換雙引號
因為雙引號的時候內部可以放變數,php會判斷內部是否有變數。
<?phpfunction test_1(){ $a ="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"; for($i=0;$i<1000;$i++){ echo $a; }}function test_2(){ $a ='1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'; for($i=0;$i<1000;$i++){ echo $a; }}test_1();//2953test_2();//2025?>
關於foreach和for迴圈效率
這篇文章已經太長了,關於foreach和for迴圈效率和檔案讀取的效率下次再單獨拿出來介紹吧