• CI框架源代码阅读笔记5 基准測试 BenchMark.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_startfunction_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}';
        }
    
    }
  • 相关阅读:
    手把手教你利用create-nuxt-app脚手架创建NuxtJS应用
    初识NuxtJS
    webpack打包Vue应用程序流程
    用选择器代替表格列的筛选功能
    Element-UI
    Spectral Bounds for Sparse PCA: Exact and Greedy Algorithms[贪婪算法选特征]
    Sparse Principal Component Analysis via Rotation and Truncation
    Generalized Power Method for Sparse Principal Component Analysis
    Sparse Principal Component Analysis via Regularized Low Rank Matrix Approximation(Adjusted Variance)
    Truncated Power Method for Sparse Eigenvalue Problems
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5275290.html
Copyright © 2020-2023  润新知