CI架構源碼閱讀筆記5 基準測試 BenchMark.php,cibenchmark.php
上一篇部落格(CI架構源碼閱讀筆記4 引導檔案CodeIgniter.php)中,我們已經看到:CI中核心流程的核心功能都是由不同的組件來完成的。這些組件類似於一個一個單獨的模組,不同的模組完成不同的功能,各模組之間可以相互調用,共同構成了CI的核心骨架。
從本篇開始,將進一步去分析各組件的實現細節,深入CI核心的黑盒內部(研究之後,其實就應該是白盒了,僅僅對於應用來說,它應該算是黑盒),從而更好的去認識、把握這個架構。
按照慣例,在開始之前,我們貼上CI中不完全的核心元件圖表:
由於BenchMark是CI中第一個載入的core組件,因此我們的分析首先從該組件開始。BenchMark的含義非常明確,使用過BenchMark工具的同學應該比較清楚,這是一個基準組件。既然是BenchMark,我們便可大膽猜想,BM組件的主要功能就是記錄程式的已耗用時間、記憶體使用量、cpu使用等情況。
先看類圖:
這個組件結構較簡單,只有一個marker內部變數和三個對外的介面:
1 Elapsed_time2 Mark3 Memory_usage
下面一個個展開來看:
1. mark
函數的簽名為:
function mark($name)
這個函數接受一個string類型的參數,而實現更簡單,只有一句話:
$this->marker[$name] = microtime();
也就是說這個函數只是用於記錄函數調用時刻的時間點。
值得注意的是,由於Controller中的特殊處理(之後我們會詳細解釋),你的應用程式控制器中可以使用$this->benchmark->mark($name);的方式來添加啟動並執行時間點,例如:
$this->benchmark->mark("function_test_start");$this->_test();$this->benchmark->mark("function_test_end");print_r($this->benchmark);
其中,function_test_start和function_test_end分別用於記錄函數調用開始和結束的時間點
列印出的結果:
現在要計算函數的調用時間,需要用到BenchMark組件的第二個函數elapsed_time
2. elapsed_time
函數的簽名為:
function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
3個參數均為選擇性參數
(1). 如果$point1 為空白,則返回’{elapsed_time}’
if ($point1 == '') { return '{elapsed_time}';}
納尼!明明應該返回的是時間,怎麼反而返回的是字串,而且這麼奇怪(類似smarty的標籤)。其實,在Output組件中,{elapsed_time}會被替換,我們暫時看一下替換的方式:
$elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');$output = str_replace('{elapsed_time}', $elapsed, $output);
也就是說,沒有指定參數的情況下,調用該函數實際得到的是total_execution_time_start這個時間點到total_execution_time_end這個時間點的時間差。更進一步,由於total_execution_time_start是在BM載入之後設定的第一個mark點(total_execution_time_end並未定義,返回的是目前時間點),該函數返回的實際就是系統的載入和已耗用時間。
(2).如果調用的是未知的mark點。則結果是未知的,直接返回空:
if ( ! isset($this->marker[$point1])){ return '';}
(3).如果沒有設定$point2的mark點,則將$point2的mark點設定為當前的時間點。
if ( ! isset($this->marker[$point2])){ $this->marker[$point2] = microtime();}
(4).最後返回的兩個mark點的時間差:
list($sm, $ss) = explode(' ', $this->marker[$point1]);list($em, $es) = explode(' ', $this->marker[$point2]);return number_format(($em + $es) - ($sm + $ss), $decimals);
還看之前的例子,這裡我們可以通過調用:
echo $this->benchmark->elapsed_time("function_test_start","function_test_end");
得到函數的執行時間.
3. memory_usage
這個函數返回的是系統的記憶體使用量情況(MB單位),與{elapsed_time} 一樣,這個函數返回的{memory_usage}也會在Output中被替換:
$memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';$output = str_replace('{memory_usage}', $memory, $output);
由於BenchMark組件本身較簡單,我們不做更多的解釋。
最後,貼上這個組件的源碼:
phpclass CI_Benchmark { /** * List of all benchmark markers and when they were added * * @var array */ var $marker = array(); /** * Set a benchmark marker * * @access public * @param string $name name of the marker * @return void */ function mark($name) { $this->marker[$name] = microtime(); } /** * Calculates the time difference between two marked points. * If the first parameter is empty this function instead returns the {elapsed_time} pseudo-variable. This permits the full system * @access public * @param string a particular marked point * @param string a particular marked point * @param integer the number of decimal places * @return mixed */ function elapsed_time($point1 = '', $point2 = '', $decimals = 4) { if ($point1 == '') { return '{elapsed_time}'; } if ( ! isset($this->marker[$point1])) { return ''; } if ( ! isset($this->marker[$point2])) { $this->marker[$point2] = microtime(); } list($sm, $ss) = explode(' ', $this->marker[$point1]); list($em, $es) = explode(' ', $this->marker[$point2]); return number_format(($em + $es) - ($sm + $ss), $decimals); } /** * Memory Usage * This function returns the {memory_usage} pseudo-variable. */ function memory_usage() { return '{memory_usage}'; }}
使用php的CI架構一般怎做單元測試?用CI內建的還是phpunit更好?
phpunit
ci 架構對mysql版本有要 為何用mysql55會報錯
不是最新的mysql.ci目前運用的很正常.
http://www.bkjia.com/PHPjc/907043.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/907043.htmlTechArticleCI架構源碼閱讀筆記5 基準測試 BenchMark.php,cibenchmark.php 上一篇部落格(CI架構源碼閱讀筆記4 引導檔案CodeIgniter.php)中,我們已經看到:CI中核...