Benchmark
[ class tree: Benchmark ] [ index: Benchmark ] [ all elements ]

Source for file Profiler.php

Documentation is available at Profiler.php

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PEAR :: Benchmark                                                    |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 2002-2005 Matthias Englert <Matthias.Englert@gmx.de>.  |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.00 of the PHP License,      |
  9. // | that is available at http://www.php.net/license/3_0.txt.             |
  10. // | If you did not receive a copy of the PHP license and are unable to   |
  11. // | obtain it through the world-wide-web, please send a note to          |
  12. // | license@php.net so we can mail you a copy immediately.               |
  13. // +----------------------------------------------------------------------+
  14. //
  15. // $Id: Profiler.php,v 1.11 2004/12/22 08:06:09 sebastian Exp $
  16. //
  17.  
  18. require_once 'PEAR.php';
  19.  
  20. /**
  21.  * Provides timing and profiling information.
  22.  *
  23.  * Example 1: Automatic profiling start, stop, and output.
  24.  *
  25.  * <code>
  26.  * <?php
  27.  * require_once 'Benchmark/Profiler.php';
  28.  *
  29.  * $profiler = new Benchmark_Profiler(TRUE);
  30.  *
  31.  * function myFunction() {
  32.  *     $profiler->enterSection('myFunction');
  33.  *     //do something
  34.  *     $profiler->leaveSection('myFunction');
  35.  *     return;
  36.  * }
  37.  *
  38.  * //do something
  39.  * myFunction();
  40.  * //do more
  41.  * ?>
  42.  * </code>
  43.  *
  44.  * Example 2: Manual profiling start, stop, and output.
  45.  *
  46.  * <code>
  47.  * <?php
  48.  * require_once 'Benchmark/Timer.php';
  49.  *
  50.  * $profiler = new Benchmark_Profiler();
  51.  *
  52.  * function myFunction() {
  53.  *     $profiler->enterSection('myFunction');
  54.  *     //do something
  55.  *     $profiler->leaveSection('myFunction');
  56.  *     return;
  57.  * }
  58.  *
  59.  * $profiler->start();
  60.  * //do something
  61.  * myFunction();
  62.  * //do more
  63.  * $profiler->stop();
  64.  * $profiler->display();
  65.  * ?>
  66.  * </code>
  67.  *
  68.  * @author    Matthias Englert <Matthias.Englert@gmx.de>
  69.  * @copyright Copyright &copy; 2002-2005 Matthias Englert <Matthias.Englert@gmx.de>
  70.  * @license   http://www.php.net/license/3_0.txt The PHP License, Version 3.0
  71.  * @category  Benchmarking
  72.  * @package   Benchmark
  73.  * @since     1.2.0
  74.  */
  75. class Benchmark_Profiler extends PEAR {
  76.     /**
  77.      * Contains the total ex. time of each section
  78.      *
  79.      * @var    array 
  80.      * @access private
  81.      */
  82.     var $_sections = array();
  83.  
  84.     /**
  85.      * Calling stack
  86.      *
  87.      * @var    array 
  88.      * @access private
  89.      */
  90.     var $_stack = array();
  91.  
  92.     /**
  93.      * Notes how often a section was entered
  94.      *
  95.      * @var    array 
  96.      * @access private
  97.      */
  98.     var $_numberOfCalls = array();
  99.  
  100.     /**
  101.      * Notes for each section how much time is spend in sub-sections
  102.      *
  103.      * @var    array 
  104.      * @access private
  105.      */
  106.     var $_subSectionsTime = array();
  107.  
  108.     /**
  109.      * Notes for each section how often it calls which section
  110.      *
  111.      * @var    array 
  112.      * @access private
  113.      */
  114.     var $_calls = array();
  115.  
  116.     /**
  117.      * Notes for each section how often it was called by which section
  118.      *
  119.      * @var    array 
  120.      * @access private
  121.      */
  122.     var $_callers = array();
  123.  
  124.     /**
  125.      * Auto-starts and stops profiler
  126.      *
  127.      * @var    boolean 
  128.      * @access private
  129.      */
  130.     var $_auto = FALSE;
  131.  
  132.     /**
  133.      * Max marker name length for non-html output
  134.      *
  135.      * @var    integer 
  136.      * @access private
  137.      */
  138.     var $_maxStringLength = 0;
  139.  
  140.     /**
  141.      * Constructor, starts profiling recording
  142.      *
  143.      * @access public
  144.      */
  145.     function Benchmark_Profiler($auto = FALSE{
  146.         $this->auto $auto;
  147.  
  148.         if ($this->auto{
  149.             $this->start();
  150.         }
  151.  
  152.         $this->PEAR();
  153.     }
  154.  
  155.     /**
  156.      * Destructor, stops profiling recording
  157.      *
  158.      * @access private
  159.      */
  160.     function _Benchmark_Profiler({
  161.         if (isset($this->auto)) {
  162.             $this->stop();
  163.             $this->display();
  164.         }
  165.     }
  166.  
  167.     /**
  168.      * Returns profiling informations for a given section.
  169.      *
  170.      * @param  string $section 
  171.      * @return array 
  172.      * @access public
  173.      */
  174.     function getSectionInformations($section 'Global'{
  175.         if (isset($this->_sections[$section])) {
  176.             $calls = array();
  177.  
  178.             if (isset($this->_calls[$section])) {
  179.                 $calls $this->_calls[$section];
  180.             }
  181.  
  182.             $callers = array();
  183.  
  184.             if (isset($this->_callers[$section])) {
  185.                 $callers $this->_callers[$section];
  186.             }
  187.  
  188.             $informations = array();
  189.  
  190.             $informations['time']       $this->_sections[$section];
  191.             $informations['percentage'number_format(100 * $this->_sections[$section$this->_sections['Global']2'.''');
  192.             $informations['calls']      $calls;
  193.             $informations['num_calls']  $this->_numberOfCalls[$section];
  194.             $informations['callers']    $callers;
  195.  
  196.               if (isset($this->_subSectionsTime[$section])) {
  197.                 $informations['netto_time'$this->_sections[$section$this->_subSectionsTime[$section];
  198.               else {
  199.                 $informations['netto_time'$this->_sections[$section];
  200.               }
  201.  
  202.             return $informations;
  203.         else {
  204.             $this->raiseError("The section '$section' does not exists.\n"NULLPEAR_ERROR_TRIGGERE_USER_WARNING);
  205.         }
  206.     }
  207.  
  208.     /**
  209.      * Returns profiling informations for all sections.
  210.      *
  211.      * @return array 
  212.      * @access public
  213.      */
  214.     function getAllSectionsInformations({
  215.         $informations = array();
  216.  
  217.         foreach($this->_sections as $section => $time{
  218.             $informations[$section$this->getSectionInformations($section);
  219.         }
  220.  
  221.         return $informations;
  222.     }
  223.  
  224.     /**
  225.      * Returns formatted profiling information.
  226.      *
  227.      * @see    display()
  228.      * @access private
  229.      */
  230.     function _getOutput({
  231.         if (function_exists('version_compare'&&
  232.             version_compare(phpversion()'4.1''ge')) {
  233.             $http = isset($_SERVER['SERVER_PROTOCOL']);
  234.         else {
  235.             global $HTTP_SERVER_VARS;
  236.             $http = isset($HTTP_SERVER_VARS['SERVER_PROTOCOL']);
  237.         }
  238.  
  239.         if ($http{
  240.             $out '<table style="border: 1px solid #000000; ">'."\n";
  241.             $out .=
  242.                 '<tr><td>&nbsp;</td><td align="center"><b>total ex. time</b></td>'.
  243.                 '<td align="center"><b>netto ex. time</b></td>'.
  244.                 '<td align="center"><b>#calls</b></td><td align="center"><b>%</b></td>'.
  245.                 '<td align="center"><b>calls</b></td><td align="center"><b>callers</b></td></tr>'.
  246.                 "\n";
  247.         else {
  248.             $dashes $out str_pad("\n"($this->_maxStringLength + 52)'-'STR_PAD_LEFT);
  249.             $out .= str_pad('section'$this->_maxStringLength);
  250.             $out .= str_pad("total ex time"22);
  251.             $out .= str_pad("netto ex time"22);
  252.             $out .= str_pad("#calls"22);
  253.             $out .= "perct\n";
  254.             $out .= $dashes;
  255.         }
  256.  
  257.         $informations $this->getAllSectionsInformations();
  258.  
  259.         foreach($informations as $name => $values{
  260.             $percentage $values['percentage'];
  261.             $calls_str "";
  262.  
  263.             foreach($values['calls'as $key => $val{
  264.                 if ($calls_str{
  265.                     $calls_str .= ", ";
  266.                 }
  267.  
  268.                 $calls_str .= "$key ($val)";
  269.             }
  270.  
  271.             $callers_str "";
  272.  
  273.             foreach($values['callers'as $key => $val{
  274.                 if ($callers_str{
  275.                     $callers_str .= ", ";
  276.                     }
  277.  
  278.                 $callers_str .= "$key ($val)";
  279.             }
  280.  
  281.             if ($http{
  282.                 $out .=
  283.                     "<tr><td><b>$name</b></td><td>{$values['time']}</td><td>{$values['netto_time']}</td><td>{$values['num_calls']}</td>".
  284.                     "<td align=\"right\">{$values['percentage']}%</td>\n";
  285.                 $out .= "<td>$calls_str</td><td>$callers_str</td></tr>";
  286.             else {
  287.                 $out .= str_pad($name$this->_maxStringLength' ');
  288.                 $out .= str_pad($values['time']22);
  289.                 $out .= str_pad($values['netto_time']22);
  290.                 $out .= str_pad($values['num_calls']22);
  291.                 $out .=
  292.  
  293.                 str_pad($values['percentage']."%\n"8' 'STR_PAD_LEFT);
  294.             }
  295.         }
  296.  
  297.         return $out '</table>';
  298.     }
  299.  
  300.     /**
  301.      * Returns formatted profiling information.
  302.      *
  303.      * @access public
  304.      */
  305.     function display({
  306.         echo $this->_getOutput();
  307.     }
  308.  
  309.     /**
  310.      * Enters "Global" section.
  311.      *
  312.      * @see    enterSection(), stop()
  313.      * @access public
  314.      */
  315.     function start({
  316.         $this->enterSection('Global');
  317.     }
  318.  
  319.     /**
  320.      * Leaves "Global" section.
  321.      *
  322.      * @see    leaveSection(), start()
  323.      * @access public
  324.      */
  325.     function stop({
  326.         $this->leaveSection('Global');
  327.     }
  328.  
  329.     /**
  330.      * Enters code section.
  331.      *
  332.      * @param  string  name of the code section
  333.      * @see    start(), leaveSection()
  334.      * @access public
  335.      */
  336.     function enterSection($name{
  337.         if (count($this->_stack)) {
  338.             if (isset($this->_callers[$name][$this->_stack[count($this->_stack- 1]["name"]])) {
  339.                 $this->_callers[$name][$this->_stack[count($this->_stack- 1]["name"]]++;
  340.             else {
  341.                 $this->_callers[$name][$this->_stack[count($this->_stack- 1]["name"]] = 1;
  342.             }
  343.  
  344.             if (isset($this->_calls[$this->_stack[count($this->_stack- 1]["name"]][$name])) {
  345.                 $this->_calls[$this->_stack[count($this->_stack- 1]["name"]][$name]++;
  346.             else {
  347.                 $this->_calls[$this->_stack[count($this->_stack- 1]["name"]][$name= 1;
  348.             }
  349.         }
  350.  
  351.         if (isset($this->_numberOfCalls[$name])) {
  352.             $this->_numberOfCalls[$name]++;
  353.         else {
  354.             $this->_numberOfCalls[$name= 1;
  355.         }
  356.  
  357.         array_push($this->_stackarray("name" => $name"time" => $this->_getMicrotime()));
  358.     }
  359.  
  360.     /**
  361.      * Leaves code section.
  362.      *
  363.      * @param  string  name of the marker to be set
  364.      * @see     stop(), enterSection()
  365.      * @access public
  366.      */
  367.     function leaveSection($name{
  368.         $microtime $this->_getMicrotime();
  369.         $x array_pop($this->_stack);
  370.  
  371.         if ($x["name"!= $name{
  372.             $this->raiseError("reached end of section $name but expecting end of " . $x["name"]."\n"NULLPEAR_ERROR_DIE);
  373.         }
  374.  
  375.         if (isset($this->_sections[$name])) {
  376.             $this->_sections[$name+= $microtime $x["time"];
  377.         else {
  378.             $this->_sections[$name$microtime $x["time"];
  379.         }
  380.  
  381.           $parent array_pop($this->_stack);
  382.  
  383.           if (isset($parent)) {
  384.             if (isset($this->_subSectionsTime[$parent['name']])) {
  385.                 $this->_subSectionsTime[$parent['name']] += $microtime $x['time'];
  386.             else {
  387.                 $this->_subSectionsTime[$parent['name']] $microtime $x['time'];
  388.             }
  389.  
  390.               array_push($this->_stack$parent);
  391.         }
  392.     }
  393.  
  394.     /**
  395.      * Wrapper for microtime().
  396.      *
  397.      * @return float 
  398.      * @access private
  399.      * @since  1.3.0
  400.      */
  401.     function _getMicrotime({
  402.         $microtime explode(' 'microtime());
  403.         return $microtime[1substr($microtime[0]1);
  404.     }
  405. }
  406. ?>

Documentation generated on Mon, 11 Mar 2019 14:00:14 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.