PHP歸檔phar效能測試
PHP自從5.3後新增PHAR歸檔,Phar 歸檔的概念來自 Java? 技術的 JAR 歸檔,它允許使用單個檔案打包應用程式,這個檔案中包含運行應用程式所需的所有東西。該檔案不同於單個可執行檔,後者通常由程式設計語言產生,比如 C,因為該檔案實際上是一個歸檔檔案而非編譯過的應用程式。因此 JAR 檔案實際上包含組成應用程式的檔案,但是考慮到安全性,不對這些檔案進行仔細區分。Phar 擴充正是基於類似的理念,但是在設計時主要針對 PHP 的 Web 環境。同樣,與 JAR 歸檔不同的是,Phar 歸檔可由 PHP 本身處理,因此不需要使用額外的工具來建立或使用。Phar 擴充對 PHP 來說並不是一個新鮮的概念。它最初使用 PHP 編寫並被命名為 PHP_Archive,然後在 2005 年被添加到 PEAR 庫。然而在實際中,解決這一問題的純 PHP 解決方案非常緩慢,因此 2007 年重新編寫為純 C 語言擴充,同時添加了使用 SPL 的 ArrayAccess 對象遍曆 Phar 歸檔的支援。自那時起,人們做了大量工作來改善 Phar 歸檔的效能,目前對Phar使用非常有限,而關於Phar的效能測試很少,到底Phar效能如何,通過一個簡單實驗檢驗下。
測試環境:
PHP:5.5.10
CPU:2GHz intel core i7
Mem:8GB
系統:Darwin 13.1.0
主要測試點:
1:Phar載入速度
1.1:檔案大小多少的影響?
1.2: include/require的影響?
1.3:Phar 存根(Stub)內容的影響?
2:Phar代碼執行速度
2.1 全域函數對比
2.2 類對象
2.3 類方法
為了保證盡量保證測試準確,每種方式運行3次,去3次的平均值。同時作為對比,我們會直接採用代碼方式,獲得基準資料。
Phar 檔案主要包含檔案
phar-builder.php用於產生phar檔案,執行test命令前,先執行此檔案產生phar-test.phar檔案。
test_load.php 測試載入phar檔案速度
src目錄內包含檔案index.php檔案是存根檔案,包含dates.php,for.php,functions.php,dates測試檔案類方法,for.php測試對象方法,functions.php測試函數方法。
具體附件代碼。
第一:phar載入速度,採用include和require方式測試發現差異不大,只採用require方式。
$stime = microtime(true);require './phar-test.phar';$etime = microtime(true);$total = $etime - $stime;echo "phar total:".$total."s";
執行後,效率如下
localhost:phar ugg$ php test_phar_load.php phar total:0.0044760704040527slocalhost:phar ugg$ php test_phar_load.php phar total:0.0051448345184326slocalhost:phar ugg$ php test_phar_load.php phar total:0.0043849945068359slocalhost:phar ugg$ vim test_phar_load.php
平均載入4.7毫秒
對比直接原始碼引用方式。
$stime = microtime(true);require './src/index.php';$etime = microtime(true);$total = $etime - $stime;echo "src total:".$total."s\n";
執行後,效率如下
localhost:phar ugg$ php test_src_load.phpsrc total:0.0026230812072754slocalhost:phar ugg$ php test_src_load.phpsrc total:0.0026969909667969slocalhost:phar ugg$ php test_src_load.phpsrc total:0.0025439262390137s
平均載入2.6毫秒
結論:通過載入速度對比,phar載入方式比直接檔案載入方式慢了不少,幾乎直接引用檔案所耗時間的兩倍。同時我又在phar檔案中載入一些幹擾檔案,使phar檔案變大,發現在10k以內,這個load時間變化不大。當然我並沒有把新增的檔案放到存根內,這樣做的目的,對於超過10K的目錄,檔案組織方式比如是autoload方式,而不會通過一個檔案包含所有的檔案。phar載入時間是src直接載入的1.8倍左右。
第二:執行速度檢驗
phar方式,代碼如下
$stime = microtime(true); //require 'phar://phar-test.phar'; require 'phar-test.phar'; $sstime = microtime(true); for($i = 0; $i<10000; ++$i){ $date = dates::next_week(); $for = new fortest(); $i = $for->for1to10000(); $number = number2Chinese('12345'); } $eetime = microtime(true); $etime = microtime(true); $total = $etime - $stime; $total2 = $eetime - $sstime; echo "phar load total:".$total."s\n"; echo "phar execution 10000 total:".$total2."s";執行效率如下
localhost:phar ugg$ php test_phar_functions.php phar load total:0.0047600269317627sphar execution 10000 total:0.00017499923706055slocalhost:phar ugg$ php test_phar_functions.php phar load total:0.004863977432251sphar execution 10000 total:0.00017404556274414slocalhost:phar ugg$ php test_phar_functions.php phar load total:0.004680871963501sphar execution 10000 total:0.00016689300537109s
執行10000次的類方法,對象執行個體和對象方法,以及函數方法,總共時間消耗為0.17毫秒。
src執行效率
localhost:phar ugg$ php test_src_functions.php phar load total:0.0029089450836182sphar execution 10000 total:0.00019693374633789slocalhost:phar ugg$ php test_src_functions.php phar load total:0.0028579235076904sphar execution 10000 total:0.0002140998840332slocalhost:phar ugg$ php test_src_functions.php phar load total:0.0029168128967285sphar execution 10000 total:0.00019478797912598s
執行10000次的類方法,對象執行個體和對象方法,以及函數方法,總共時間消耗為0.20毫秒。
小結:通過執行速度對比,發現是phar方式,執行速度,要比直接檔案include方式,快了(0.20-0.17)/0.20*100=15%,phar方式執行速度快的具體原因沒有找到,網上有份資料,apc+include_path設定 phar執行速度很快。https://github.com/ralphschindler/test-phar-performance-apc/。
總結:PHP歸檔phar方式,載入速度要慢於正常檔案包含方式,但是執行速度要高於檔案包含方式,如果配合include_path設定和APC或者OP方式,最佳化phar歸檔的載入速度,就能提升php的執行速度。下一步會做方面的嘗試,1:構建大phar檔案,實驗載入速度,執行速度。2:瞭解phar載入原理和執行原理,3:包概念管理和依賴。
其他一些參考資料
PHP V5.3中新特性,建立並使用Phar歸檔。http://www.ibm.com/developerworks/cn/opensource/os-php-5.3new4/
test-phar-performance-apc https://github.com/ralphschindler/test-phar-performance-apc/