程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP前端開發中的性能那點事

PHP前端開發中的性能那點事

編輯:關於PHP編程

     在我們平時的php開發中,一個大的項目經過長時間的積累以後你會發現性能越來越慢,而性能到底消耗在了什麼地方,常常是一個令人頭疼的問題,function a()調用了多少次,function b()又消耗了多少時間,我們到底怎麼查找是哪個蛀蟲拉慢了我們的程序運行速度呢?在這裡給大家介紹一款工具xdebug,相信很多人已經聽說過了,希望借助這個工具我們可以起到簡單分析php程序性能瓶頸的問題。

    A)假設1,假設用戶目錄在/home/ad
    B)假設2,假設php目錄在/home/ad/php

    1、xdebug簡介與安裝
    Xdebug是一個開放源代碼的PHP程序調試器(即一個Debug工具),可以用來跟蹤,調試和分析PHP程序的運行狀況。
    1)下載xdebug
    xdebug的官方下載地址為:http://xdebug.org/download.php
    最新版本為:Xdebug 2.1.0
    2)xdebug的安裝

    1 2 3 4 5 6 7 8 cd /home/ad wget  http://xdebug.org/files/xdebug-2.1.0.tgz tar -zxvf xdebug-2.1.0.tgz cd xdebug-2.1.0 /home/ad/php/bin/phpize ./configure --enable-xdebug --with-php-config=/home/ad/php/bin/php-config make make install

    安裝完以後會提示你擴展安裝到了哪個目錄,類似  /home/ad/php/lib/php/extensions/no-debug-non-zts-20060613/
    假設你的php.ini放在 /home/ad/php/lib/php.ini
    加上

    1 2 3 4 5 6 7 8 9 [xdebug] zend_extension = "/home/ad/php/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so" xdebug.auto_trace = on xdebug.auto_profile = on xdebug.collect_params = on xdebug.collect_return = on xdebug.profiler_enable = on xdebug.trace_output_dir = "/home/ad/xdebug_log" xdebug.profiler_output_dir = "/home/ad/xdebug_log"

    重啟apache
    去/home/ad/xdebug_log下看看是不是日志已經出來了

    2、xdebug參數簡介
    zend_extension 加載xdebug擴展
    xdebug.auto_trace 自動打開打開函數調用監測
    xdebug.auto_profile 自動打開性能監測
    xdebug.trace_output_dir 設定函數調用監測信息的輸出文件的路徑。
    xdebug.profiler_output_dir 設定效能監測信息輸出文件的路徑。
    xdebug.collect_params 打開收集“函數參數”的功能。將函數調用的參數值列入函數過程調用的監測信息中。
    xdebug.collect_return 打開收集“函數返回值”的功能。將函數的返回值列入函數過程調用的監測信息中。

    3、示例程序與日志收集

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php function a() {     echo "aaa";    } function b() {     a();     sleep(1);     a();     sleep(1);     a();    } b(); ?>

     

     

    4、日志分析工具wincachegrind
    http://sourceforge.net/projects/wincachegrind/
    不用安裝直接雙擊就可以打開了
    我們用它打開剛才收集的日志cachegrind.out.***

     

    前端開發中的性能那點事(二)巧用curl 並發減少後端訪問時間

    前言:
    在我們平時的程序中難免出現同時訪問幾個接口的情況,平時我們用curl進行訪問的時候,一般都是單個、順序訪問,假如有3個接口,每個接口耗時500毫秒那麼我們三個接口就要花費1500毫秒了,這個問題太頭疼了嚴重影響了頁面訪問速度,有沒有可能並發訪問來提高速度呢?今天就簡單的說一下,利用curl並發來提高頁面訪問速度,
    希望大家多指導。
    1、老的curl訪問方式以及耗時統計

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?php function curl_fetch($url, $timeout=3){     $ch = curl_init();     curl_setopt($ch, CURLOPT_URL, $url);     curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);     $data = curl_exec($ch);     $errno = curl_errno($ch);     if ($errno>0) {         $data = false;     }     curl_close($ch);     return $data; } function microtime_float() {    list($usec, $sec) = explode(" ", microtime());    return ((float)$usec + (float)$sec); } $url_arr=array(      "taobao"=>"http://www.taobao.com",      "sohu"=>"http://www.sohu.com",      "sina"=>"http://www.sina.com.cn",      );  $time_start = microtime_float();  $data=array();  foreach ($url_arr as $key=>$val)  {      $data[$key]=curl_fetch($val);  }  $time_end = microtime_float();  $time = $time_end - $time_start;  echo "耗時:{$time}"; ?>

    耗時:0.614秒
    2、curl並發訪問方式以及耗時統計

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 <?php function curl_multi_fetch($urlarr=array()){     $result=$res=$ch=array();     $nch = 0;     $mh = curl_multi_init();     foreach ($urlarr as $nk => $url) {         $timeout=2;         $ch[$nch] = curl_init();         curl_setopt_array($ch[$nch], array(         CURLOPT_URL => $url,         CURLOPT_HEADER => false,         CURLOPT_RETURNTRANSFER => true,         CURLOPT_TIMEOUT => $timeout,         ));         curl_multi_add_handle($mh, $ch[$nch]);         ++$nch;     }     /* wait for performing request */     do {         $mrc = curl_multi_exec($mh, $running);     } while (CURLM_CALL_MULTI_PERFORM == $mrc);        while ($running && $mrc == CURLM_OK) {         // wait for network         if (curl_multi_select($mh, 0.5) > -1) {             // pull in new data;             do {                 $mrc = curl_multi_exec($mh, $running);             } while (CURLM_CALL_MULTI_PERFORM == $mrc);         }     }        if ($mrc != CURLM_OK) {         error_log("CURL Data Error");     }        /* get data */     $nch = 0;     foreach ($urlarr as $moudle=>$node) {         if (($err = curl_error($ch[$nch])) == '') {             $res[$nch]=curl_multi_getcontent($ch[$nch]);             $result[$moudle]=$res[$nch];         }         else         {             error_log("curl error");         }         curl_multi_remove_handle($mh,$ch[$nch]);         curl_close($ch[$nch]);         ++$nch;     }     curl_multi_close($mh);     return  $result; } $url_arr=array(      "taobao"=>"http://www.taobao.com",      "sohu"=>"http://www.sohu.com",      "sina"=>"http://www.sina.com.cn",      ); function microtime_float() {    list($usec, $sec) = explode(" ", microtime());    return ((float)$usec + (float)$sec); } $time_start = microtime_float(); $data=curl_multi_fetch($url_arr); $time_end = microtime_float(); $time = $time_end - $time_start;  echo "耗時:{$time}"; ?>

     

     

    耗時:0.316秒
    帥氣吧整個頁面訪問後端接口的時間節省了一半
    3、curl相關參數
    來自:http://cn2.php.net/manual/en/ref.curl.php
    curl_close — Close a cURL session
    curl_copy_handle — Copy a cURL handle along with all of its preferences
    curl_errno — Return the last error number
    curl_error — Return a string containing the last error for the current session
    curl_exec — Perform a cURL session
    curl_getinfo — Get information regarding a specific transfer
    curl_init — Initialize a cURL session
    curl_multi_add_handle — Add a normal cURL handle to a cURL multi handle
    curl_multi_close — Close a set of cURL handles
    curl_multi_exec — Run the sub-connections of the current cURL handle
    curl_multi_getcontent — Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set
    curl_multi_info_read — Get information about the current transfers
    curl_multi_init — Returns a new cURL multi handle
    curl_multi_remove_handle — Remove a multi handle from a set of cURL handles
    curl_multi_select — Wait for activity on any curl_multi connection
    curl_setopt_array — Set multiple options for a cURL transfer
    curl_setopt — Set an option for a cURL transfer
    curl_version — Gets cURL version information


    前端開發中的性能那點事(三)php的opcode緩存

     

    前言:由php的運行機制決定,其實php在運行階段我們也是可以進行緩存的從而提高程序運行效率,這就是我們常說的opcode緩存。
    1、簡述php的運行機制
    (因為本文是寫opcode緩存的所以這裡只是簡要概述,後邊會專門寫一篇揭秘php運行機制的。)
    a).php文件通過浏覽器過來
    b)請求交給SAPI,隨後SAPI層將控制權轉給PHP
    c)zend_language_scanner對代碼進行掃描,對php代碼進行詞法分析轉換成一系列的tokens array
    d)zend_language_parser將c步驟產生的一系列tokens處理掉空格等無用的代碼以後轉換成一系列表達式
    e)經過compiler階段生成opcode返回zend_op_array指針
    f)zend_vm_execute根據傳入的zend_op_array指針,執行opcode並將結果返回輸出


    PHP前端開發中的性能那點事 三聯


    2、opcode簡介
    Opcode是operation code(操作碼)的簡稱,其實就是第一小節c)、d)、e)步驟產生的一種中間碼,
    opcode是一個四元組,(opcode, op1, op2, result),它們分別代表操作碼,第一操作數,第二操作數,結果。
    如:

    1 2 3 <?php echo "taobao search blog"; ?>

    對應的tokens

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 Array (     [0] => Array         (             [0] => 367             [1] => <?php             [2] => 1         )        [1] => Array         (             [0] => 316             [1] => echo             [2] => 1         )        [2] => Array         (             [0] => 370             [1] =>             [2] => 1         )        [3] => Array         (             [0] => 315             [1] => "taobao search blog"             [2] => 1         )        [4] => ;     [5] => Array         (             [0] => 370             [1] =>             [2] => 1         )        [6] => Array         (             [0] => 369             [1] => ?>             [2] => 1         )    )

    對應的opcode就是

    1 2 3 4 5 line     # *  op                           fetch          ext  return  operands ---------------------------------------------------------------------------------    2     0  >   ECHO                                                     'taobao+search+blog'    4     1    > RETURN                                                   1          2*   > ZEND_HANDLE_EXCEPTION

    3、使用apc對opcode緩存
    a)假設php路徑為/home/ad/php
    對opcode進行緩存的軟件很多(apc、eAcclerator、Xcache、Zend Platform),這裡主要介紹apc
    APC提供兩種緩存功能,即緩存Opcode(目標文件),我們稱之為apc_compiler_cache。同時它還提供一些接口用於PHP開發人員將用戶數據駐留在內存中,我們稱之為apc_user_cache。我們這裡主要討論apc_compiler_cache的配置。
    下載地址:http://pecl.php.net/package/APC
    最新版本為APC-3.1.6.tgz

    1 2 3 4 5 6 7 wget http://pecl.php.net/get/APC-3.1.6.tgz tar -zxvf APC-3.1.6.tgz cd APC-3.1.6 /home/ad/php/bin/phpize ./configure --enable-apc --enable-apc-mmap  --with-php-config=/home/ad/php/bin/php-config make make install

    編輯php.ini
    添加apc的配置

    1 2 3 4 5 6 7 8 9 10 11 12 13 [apc] extension=apc.so apc.enabled=1 apc.shm_segments = 1 apc.shm_size = 128 apc.ttl = 0 apc.user_ttl = 7200 apc.num_files_hint = 1000 apc.write_lock=1 apc.stat = 0 apc.max_file_size=1M apc.filters = a.php,b.php apc.cache_by_default=1

    重新apache就ok啦

    4、常用參數的解析
    apc.enabled 開啟apc 設置為0關閉,1為開啟
    apc.shm_segments 共享內存塊數
    apc.shm_size 共享內存大小,但是是M
    那麼顯然共享內存的總數就是apc.shm_segments*apc.shm_size
    apc.num_files_hint 允許多少個opcode被緩存
    apc.stat 為1的時候會自動檢查opcode對應的php文件是否有更新,有更新的話會自動更新。設置為0的話就不會去檢查了這樣會提高apc的效率,但是要使php的修改生效的話就必須重啟apache了,或者使用函數apc_cache_clear()來清空緩存
    apc.ttl opcode緩存的過期時間,設置為0表示不過期,如果不為0會檢查兩次請求之間的時間,如果時間大於設置值那麼會更新opcode緩存
    apc.write_lock 表示多個進程同時更新一份opcode緩存的時候那麼只讓最先的一個生效,可以有效避免寫沖突
    apc.max_file_size 超過設置值大小的文件不被緩存
    apc.filters 需要特例的文件,多個文件用逗號(,)相隔
    apc.filters 與 apc.cache_by_default結合使用,
    當apc.cache_by_default為1時apc.filters文件不被緩存,當apc.cache_by_default為0時僅apc.filters文件被緩存

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved