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_STRICT
class 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%左右。
二、使用靜態變量和方法
測試結果如下
<?php
class 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微秒
?>
三、盡量不適用@符號
說實話我沒見到過必須使用@符號的地方
<?php
class 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,133
test_2(); //48,381
?>
四、使用php內置的變量來代替一些函數。
某些時候也可以用$_SERVER[‘REQUEST_TIME’]替換time()。、
這個性能的提示我測試出的結果讓我都有些不能相信
<?php
function 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循環的條件中,不要在循環中聲明不必要的變量等。
<?php
function 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,602
test_2();//223
?>
六、盡量用php內置的函數替換正則
這個網上有很多對比的,我就不再重新寫一遍了;
直接給一下常用的三個函數性能對比:str_replace > strtr > preg_replace
七、包含文件有技巧
包含文件的時候,如果能確定不會重復包含,盡量使用include,require不要用include_once和require_once,而且包含錯誤(一般you 函數和變量被覆蓋)通常是可以被測試出來的。
測試結果如下:
<?php
function 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,477
test_2();//152,704
?>
八、可以用全等號代替雙等
這個相信有很多人都知道,因為雙等號是會有類型轉換的。
測試結果如下:
<?php
function 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微秒
?>
九、多維數組賦值可以使用引用來提高性能
多維數組越復雜,引用帶來的性能提高越大,引用可以減少數組元素的哈希查找次數。
<?php
function 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();//1270
test_2();//1015
//多維數組越復雜,引用帶來的性能提高越大,引用可以減少數組元素的哈希查找
?>
十、大的數組或數據如果使用完畢,及時unset掉
這個就不用過多解釋了,節省內存。
十一、不做無意義的封裝
如果不能實現特別好的設計,解耦,復用效果可以不封裝簡單方法
因為每次調用方法都會開辟一個新的內存區域,傳值的時候對數據的引用也會增加。
十二、為代碼和數據做緩存
這個數據緩存就不用說了,可能有部分朋友不知道代碼緩存,代碼緩存節省代碼運行時間的遠離:php是解釋型語言,和編譯型語言的區別如下:
編譯型語言:編程完成后,通過預處理->編譯->匯編->鏈接后變成可執行程序(計算機直接運行的二進制文件),以后每次運行都直接運行這個可執行性文件。
解釋型語言:具體的過程這里也說不清楚,可以理解為,解釋型語言每次運行的時候都相當於進行了上面編譯型語言編譯的過程(其實還不太一樣)生成可執行的文件。
opcache就是把解釋后的文件存入了內存,每次運行的時候就不用經過解釋的過程,可以提高20%-100%的性能(數據來自網絡,但是原理上肯定是能提升性能的,如果代碼經常迭代的話慎用)。
十三、用單引號替換雙引號
因為雙引號的時候內部可以放變量,php會判斷內部是否有變量。
<?php
function 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();//2953
test_2();//2025
?>
關於foreach和for循環效率
這篇文章已經太長了,關於foreach和for循環效率和文件讀取的效率下次再單獨拿出來介紹吧
