程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> CI框架源碼閱讀筆記5 基准測試 BenchMark.php,cibenchmark.php

CI框架源碼閱讀筆記5 基准測試 BenchMark.php,cibenchmark.php

編輯:關於PHP編程

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_time
2 Mark
3 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組件本身較簡單,我們不做更多的解釋。

最後,貼上這個組件的源碼:

<?php

class 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目前運用的很正常.
 

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