diff options
Diffstat (limited to 'buildscripts/Benchmark')
| -rw-r--r-- | buildscripts/Benchmark/Iterate.php | 167 | ||||
| -rw-r--r-- | buildscripts/Benchmark/LICENSE | 22 | ||||
| -rw-r--r-- | buildscripts/Benchmark/Profiler.php | 447 | ||||
| -rw-r--r-- | buildscripts/Benchmark/Timer.php | 319 | ||||
| -rw-r--r-- | buildscripts/Benchmark/doc/timer_example.php | 18 | 
5 files changed, 973 insertions, 0 deletions
diff --git a/buildscripts/Benchmark/Iterate.php b/buildscripts/Benchmark/Iterate.php new file mode 100644 index 00000000..acf1ec08 --- /dev/null +++ b/buildscripts/Benchmark/Iterate.php @@ -0,0 +1,167 @@ +<?php
 +//
 +// +------------------------------------------------------------------------+
 +// | PEAR :: Benchmark                                                      |
 +// +------------------------------------------------------------------------+
 +// | Copyright (c) 2001-2006 Sebastian Bergmann <sb@sebastian-bergmann.de>. |
 +// +------------------------------------------------------------------------+
 +// | This source file is subject to the New BSD license, That is bundled    |
 +// | with this package in the file LICENSE, and is available through        |
 +// | the world-wide-web at                                                  |
 +// | http://www.opensource.org/licenses/bsd-license.php                     |
 +// | If you did not receive a copy of the new BSDlicense and are unable     |
 +// | to obtain it through the world-wide-web, please send a note to         |
 +// | license@php.net so we can mail you a copy immediately.                 |
 +// +------------------------------------------------------------------------+
 +//
 +// $Id: Iterate.php,v 1.12 2006/02/17 16:29:44 toggg Exp $
 +//
 +
 +require_once 'Benchmark/Timer.php';
 +
 +/**
 + * Provides timing and profiling information.
 + *
 + * Example 1
 + *
 + * <code>
 + * <?php
 + * require_once 'Benchmark/Iterate.php';
 + *
 + * $benchmark = new Benchmark_Iterate;
 + *
 + * function foo($string) {
 + *     print $string . '<br>';
 + * }
 + *
 + * $benchmark->run(100, 'foo', 'test');
 + * $result = $benchmark->get();
 + * ?>
 + * </code>
 + *
 + * Example 2
 + *
 + * <code>
 + * <?php
 + * require_once 'Benchmark/Iterate.php';
 + *
 + * $benchmark = new Benchmark_Iterate;
 + *
 + * class MyClass {
 + *     function foo($string) {
 + *         print $string . '<br>';
 + *     }
 + * }
 + *
 + * $benchmark->run(100, 'myclass::foo', 'test');
 + * $result = $benchmark->get();
 + * ?>
 + * </code>
 + *
 + * Example 3
 + *
 + * <code>
 + * <?php
 + * require_once 'Benchmark/Iterate.php';
 + *
 + * $benchmark = new Benchmark_Iterate;
 + *
 + * class MyClass {
 + *     function foo($string) {
 + *         print $string . '<br>';
 + *     }
 + * }
 + *
 + * $o = new MyClass();
 + *
 + * $benchmark->run(100, 'o->foo', 'test');
 + * $result = $benchmark->get();
 + * ?>
 + * </code>
 + *
 + * @author    Sebastian Bergmann <sb@sebastian-bergmann.de>
 + * @copyright Copyright © 2002-2005 Sebastian Bergmann <sb@sebastian-bergmann.de>
 + * @license   http://www.php.net/license/3_0.txt The PHP License, Version 3.0
 + * @category  Benchmarking
 + * @package   Benchmark
 + */
 +class Benchmark_Iterate extends Benchmark_Timer {
 +    /**
 +     * Benchmarks a function or method.
 +     *
 +     * @access public
 +     */
 +    function run() {
 +        $arguments     = func_get_args();
 +        $iterations    = array_shift($arguments);
 +        $function_name = array_shift($arguments);
 +
 +        if (strstr($function_name, '::')) {
 +          $function_name = explode('::', $function_name);
 +          $objectmethod = $function_name[1];
 +        }
 +
 +        if (strstr($function_name, '->')) {
 +            $function_name = explode('->', $function_name);
 +            $objectname = $function_name[0];
 +
 +            $object = $GLOBALS[$objectname];
 +            $objectmethod = $function_name[1];
 +
 +            for ($i = 1; $i <= $iterations; $i++) {
 +                $this->setMarker('start_' . $i);
 +                call_user_func_array(array($object, $function_name[1]), $arguments);
 +                $this->setMarker('end_' . $i);
 +            }
 +
 +            return(0);
 +        }
 +
 +        for ($i = 1; $i <= $iterations; $i++) {
 +            $this->setMarker('start_' . $i);
 +            call_user_func_array($function_name, $arguments);
 +            $this->setMarker('end_' . $i);
 +        }
 +    }
 +
 +    /**
 +     * Returns benchmark result.
 +     *
 +     * $result[x           ] = execution time of iteration x
 +     * $result['mean'      ] = mean execution time
 +     * $result['iterations'] = number of iterations
 +     *
 +     * @return array
 +     * @access public
 +     */
 +    function get($simple_output = false) {
 +        $result = array();
 +        $total  = 0;
 +
 +        $iterations = count($this->markers)/2;
 +
 +        for ($i = 1; $i <= $iterations; $i++) {
 +            $time = $this->timeElapsed('start_'.$i , 'end_'.$i);
 +
 +            if (extension_loaded('bcmath')) {
 +                $total = bcadd($total, $time, 6);
 +            } else {
 +                $total = $total + $time;
 +            }
 +
 +            if (!$simple_output) {
 +                $result[$i] = $time;
 +            }
 +        }
 +
 +        if (extension_loaded('bcmath')) {
 +            $result['mean'] = bcdiv($total, $iterations, 6);
 +        } else {
 +            $result['mean'] = $total / $iterations;
 +        }
 +
 +        $result['iterations'] = $iterations;
 +
 +        return $result;
 +    }
 +}
 diff --git a/buildscripts/Benchmark/LICENSE b/buildscripts/Benchmark/LICENSE new file mode 100644 index 00000000..db25e880 --- /dev/null +++ b/buildscripts/Benchmark/LICENSE @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without modification
 +, are permitted provided that the following conditions are met:
 +
 +1. Redistributions of source code must retain the above copyright notice, th
 +   is list of conditions and the following disclaimer.
 +
 +2. Redistributions in binary form must reproduce the above copyright notice,
 +   this list of conditions and the following disclaimer in the documentation and/
 +   or other materials provided with the distribution.
 +
 +3. The name of the author may not be used to endorse or promote products derived
 +   from this software without specific prior written permission.
 +
 +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WA
 +RRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABIL
 +ITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 +AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR C
 +ONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
 +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOW
 +EVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILI
 +TY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE U
 +SE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 diff --git a/buildscripts/Benchmark/Profiler.php b/buildscripts/Benchmark/Profiler.php new file mode 100644 index 00000000..e9108a84 --- /dev/null +++ b/buildscripts/Benchmark/Profiler.php @@ -0,0 +1,447 @@ +<?php
 +//
 +// +----------------------------------------------------------------------+
 +// | PEAR :: Benchmark                                                    |
 +// +----------------------------------------------------------------------+
 +// | Copyright (c) 2002-2006 Matthias Englert <Matthias.Englert@gmx.de>.  |
 +// +----------------------------------------------------------------------+
 +// | This source file is subject to the New BSD license, That is bundled  |
 +// | with this package in the file LICENSE, and is available through      |
 +// | the world-wide-web at                                                |
 +// | http://www.opensource.org/licenses/bsd-license.php                   |
 +// | If you did not receive a copy of the new BSDlicense and are unable   |
 +// | to obtain it through the world-wide-web, please send a note to       |
 +// | license@php.net so we can mail you a copy immediately.               |
 +// +----------------------------------------------------------------------+
 +//
 +// $Id: Profiler.php,v 1.19 2006/03/01 19:26:09 anant Exp $
 +//
 +
 +require_once 'PEAR.php';
 +
 +/**
 + * Provides timing and profiling information.
 + *
 + * Example 1: Automatic profiling start, stop, and output.
 + *
 + * <code>
 + * <?php
 + * require_once 'Benchmark/Profiler.php';
 + *
 + * $profiler = new Benchmark_Profiler(TRUE);
 + *
 + * function myFunction() {
 + *     global $profiler;
 + *     $profiler->enterSection('myFunction');
 + *     //do something
 + *     $profiler->leaveSection('myFunction');
 + *     return;
 + * }
 + *
 + * //do something
 + * myFunction();
 + * //do more
 + * ?>
 + * </code>
 + *
 + * Example 2: Manual profiling start, stop, and output.
 + *
 + * <code>
 + * <?php
 + * require_once 'Benchmark/Profiler.php';
 + *
 + * $profiler = new Benchmark_Profiler();
 + *
 + * function myFunction() {
 + *     global $profiler;
 + *     $profiler->enterSection('myFunction');
 + *     //do something
 + *     $profiler->leaveSection('myFunction');
 + *     return;
 + * }
 + *
 + * $profiler->start();
 + * //do something
 + * myFunction();
 + * //do more
 + * $profiler->stop();
 + * $profiler->display();
 + * ?>
 + * </code>
 + *
 + * @author    Matthias Englert <Matthias.Englert@gmx.de>
 + * @copyright Copyright © 2002-2005 Matthias Englert <Matthias.Englert@gmx.de>
 + * @license   http://www.php.net/license/3_0.txt The PHP License, Version 3.0
 + * @category  Benchmarking
 + * @package   Benchmark
 + * @since     1.2.0
 + */
 +class Benchmark_Profiler extends PEAR {
 +    /**
 +     * Contains the total ex. time of each section
 +     *
 +     * @var    array
 +     * @access private
 +     */
 +    var $_sections = array();
 +
 +    /**
 +     * Calling stack
 +     *
 +     * @var    array
 +     * @access private
 +     */
 +    var $_stack = array();
 +
 +    /**
 +     * Notes how often a section was entered
 +     *
 +     * @var    array
 +     * @access private
 +     */
 +    var $_numberOfCalls = array();
 +
 +    /**
 +     * Notes for each section how much time is spend in sub-sections
 +     *
 +     * @var    array
 +     * @access private
 +     */
 +    var $_subSectionsTime = array();
 +
 +    /**
 +     * Notes for each section how often it calls which section
 +     *
 +     * @var    array
 +     * @access private
 +     */
 +    var $_calls = array();
 +
 +    /**
 +     * Notes for each section how often it was called by which section
 +     *
 +     * @var    array
 +     * @access private
 +     */
 +    var $_callers = array();
 +
 +    /**
 +     * Auto-starts and stops profiler
 +     *
 +     * @var    boolean
 +     * @access private
 +     */
 +    var $_auto = FALSE;
 +
 +    /**
 +     * Max marker name length for non-html output
 +     *
 +     * @var    integer
 +     * @access private
 +     */
 +    var $_maxStringLength = 0;
 +
 +    /**
 +     * Constructor, starts profiling recording
 +     *
 +     * @access public
 +     */
 +    function Benchmark_Profiler($auto = FALSE) {
 +        $this->_auto = $auto;
 +
 +        if ($this->_auto) {
 +            $this->start();
 +        }
 +
 +        $this->PEAR();
 +    }
 +
 +    /**
 +     * Destructor, stops profiling recording
 +     *
 +     * @access private
 +     */
 +    function _Benchmark_Profiler() {
 +        if (isset($this->_auto) && $this->_auto) {
 +            $this->stop();
 +            $this->display();
 +        }
 +    }
 +
 +    /**
 +     * Returns profiling informations for a given section.
 +     *
 +     * @param  string $section
 +     * @return array
 +     * @access public
 +     */
 +    function getSectionInformations($section = 'Global') {
 +        if (isset($this->_sections[$section])) {
 +            $calls = array();
 +
 +            if (isset($this->_calls[$section])) {
 +                $calls = $this->_calls[$section];
 +            }
 +
 +            $callers = array();
 +
 +            if (isset($this->_callers[$section])) {
 +                $callers = $this->_callers[$section];
 +            }
 +
 +            $informations = array();
 +
 +            $informations['time']       = $this->_sections[$section];
 +            if (isset($this->_sections['Global'])) {
 +                $informations['percentage'] = number_format(100 * $this->_sections[$section] / $this->_sections['Global'], 2, '.', '');
 +            } else {
 +                $informations['percentage'] = 'N/A';
 +            }
 +            $informations['calls']      = $calls;
 +            $informations['num_calls']  = $this->_numberOfCalls[$section];
 +            $informations['callers']    = $callers;
 +
 +      	    if (isset($this->_subSectionsTime[$section])) {
 +                $informations['netto_time'] = $this->_sections[$section] - $this->_subSectionsTime[$section];
 +      	    } else {
 +                $informations['netto_time'] = $this->_sections[$section];
 +      	    }
 +
 +            return $informations;
 +        } else {
 +            $this->raiseError("The section '$section' does not exists.\n", NULL, PEAR_ERROR_TRIGGER, E_USER_WARNING);
 +        }
 +    }
 +
 +    /**
 +     * Returns profiling informations for all sections.
 +     *
 +     * @return array
 +     * @access public
 +     */
 +    function getAllSectionsInformations() {
 +        $informations = array();
 +
 +        foreach($this->_sections as $section => $time) {
 +            $informations[$section] = $this->getSectionInformations($section);
 +        }
 +
 +        return $informations;
 +    }
 +
 +    /**
 +     * Returns formatted profiling information.
 +     *
 +     * @param  string output format (auto, plain or html), default auto
 +     * @see    display()
 +     * @access private
 +     */
 +    function _getOutput($format) {
 +        
 +        /* Quickly find out the maximun length: Ineffecient, but will do for now! */
 +        $informations = $this->getAllSectionsInformations();
 +        $names = array_keys($informations);
 +        
 +        $maxLength = 0;
 +        foreach ($names as $name)
 +        {
 +            if ($maxLength < strlen($name)) {
 +                $maxLength = strlen($name);
 +            }
 +        }
 +        $this->_maxStringLength = $maxLength;
 +
 +        if ($format == 'auto') {
 +            if (function_exists('version_compare') &&
 +                version_compare(phpversion(), '4.1', 'ge')) {
 +                $format = isset($_SERVER['SERVER_PROTOCOL']) ? 'html' : 'plain';
 +            } else {
 +                global $HTTP_SERVER_VARS;
 +                $format = isset($HTTP_SERVER_VARS['SERVER_PROTOCOL']) ? 'html' : 'plain';
 +            }
 +        }
 +
 +        if ($format == 'html') {
 +            $out = '<table style="border: 1px solid #000000; ">'."\n";
 +            $out .=
 +                '<tr><td> </td><td align="center"><b>total ex. time</b></td>'.
 +                '<td align="center"><b>netto ex. time</b></td>'.
 +                '<td align="center"><b>#calls</b></td><td align="center"><b>%</b></td>'.
 +                '<td align="center"><b>calls</b></td><td align="center"><b>callers</b></td></tr>'.
 +                "\n";
 +        } else {
 +            $dashes = $out = str_pad("\n", ($this->_maxStringLength + 75), '-', STR_PAD_LEFT);
 +            $out .= str_pad('Section', $this->_maxStringLength + 10);
 +            $out .= str_pad("Total Ex Time", 22);
 +            $out .= str_pad("Netto Ex Time", 22);
 +            $out .= str_pad("#Calls", 10);
 +            $out .= "Percentage\n";
 +            $out .= $dashes;
 +        }
 +           
 +        foreach($informations as $name => $values) {
 +            $percentage = $values['percentage'];
 +            $calls_str = "";
 +
 +            foreach($values['calls'] as $key => $val) {
 +                if ($calls_str) {
 +                    $calls_str .= ", ";
 +                }
 +
 +                $calls_str .= "$key ($val)";
 +            }
 +
 +            $callers_str = "";
 +
 +            foreach($values['callers'] as $key => $val) {
 +                if ($callers_str) {
 +                    $callers_str .= ", ";
 +    		        }
 +
 +                $callers_str .= "$key ($val)";
 +            }
 +
 +            if ($format == 'html') {
 +                $out .= "<tr><td><b>$name</b></td><td>{$values['time']}</td><td>{$values['netto_time']}</td><td>{$values['num_calls']}</td>";
 +                if (is_numeric($values['percentage'])) {
 +                    $out .= "<td align=\"right\">{$values['percentage']}%</td>\n";
 +                } else {
 +                    $out .= "<td align=\"right\">{$values['percentage']}</td>\n";
 +                }
 +                $out .= "<td>$calls_str</td><td>$callers_str</td></tr>";
 +            } else {
 +                $out .= str_pad($name, $this->_maxStringLength + 10);
 +                $out .= str_pad($values['time'], 22);
 +                $out .= str_pad($values['netto_time'], 22);
 +                $out .= str_pad($values['num_calls'], 10);
 +                if (is_numeric($values['percentage'])) {
 +                    $out .= str_pad($values['percentage']."%\n", 8, ' ', STR_PAD_LEFT);
 +                } else {
 +                    $out .= str_pad($values['percentage']."\n", 8, ' ', STR_PAD_LEFT);
 +                }
 +            }
 +        }
 +        
 +        if ($format == 'html') {
 +            return $out . '</table>';
 +        } else {
 +            return $out;
 +        }
 +    }
 +
 +    /**
 +     * Returns formatted profiling information.
 +     *
 +     * @param  string output format (auto, plain or html), default auto
 +     * @access public
 +     */
 +    function display($format = 'auto') {
 +        echo $this->_getOutput($format);
 +    }
 +
 +    /**
 +     * Enters "Global" section.
 +     *
 +     * @see    enterSection(), stop()
 +     * @access public
 +     */
 +    function start() {
 +        $this->enterSection('Global');
 +    }
 +
 +    /**
 +     * Leaves "Global" section.
 +     *
 +     * @see    leaveSection(), start()
 +     * @access public
 +     */
 +    function stop() {
 +        $this->leaveSection('Global');
 +    }
 +
 +    /**
 +     * Enters code section.
 +     *
 +     * @param  string  name of the code section
 +     * @see    start(), leaveSection()
 +     * @access public
 +     */
 +    function enterSection($name) {
 +        if (count($this->_stack)) {
 +            if (isset($this->_callers[$name][$this->_stack[count($this->_stack) - 1]["name"]])) {
 +                $this->_callers[$name][$this->_stack[count($this->_stack) - 1]["name"]]++;
 +            } else {
 +                $this->_callers[$name][$this->_stack[count($this->_stack) - 1]["name"]] = 1;
 +            }
 +
 +            if (isset($this->_calls[$this->_stack[count($this->_stack) - 1]["name"]][$name])) {
 +                $this->_calls[$this->_stack[count($this->_stack) - 1]["name"]][$name]++;
 +            } else {
 +                $this->_calls[$this->_stack[count($this->_stack) - 1]["name"]][$name] = 1;
 +            }
 +        } else {
 +            if ($name != 'Global') {
 +                $this->raiseError("tried to enter section ".$name." but profiling was not started\n", NULL, PEAR_ERROR_DIE);
 +            }
 +        }
 +
 +        if (isset($this->_numberOfCalls[$name])) {
 +            $this->_numberOfCalls[$name]++;
 +        } else {
 +            $this->_numberOfCalls[$name] = 1;
 +        }
 +
 +        array_push($this->_stack, array("name" => $name, "time" => $this->_getMicrotime()));
 +    }
 +
 +    /**
 +     * Leaves code section.
 +     *
 +     * @param  string  name of the marker to be set
 +     * @see     stop(), enterSection()
 +     * @access public
 +     */
 +    function leaveSection($name) {
 +        $microtime = $this->_getMicrotime();
 +
 +        if (!count($this->_stack)) {
 +            $this->raiseError("tried to leave section ".$name." but profiling was not started\n", NULL, PEAR_ERROR_DIE);
 +        }
 +
 +        $x = array_pop($this->_stack);
 +
 +        if ($x["name"] != $name) {
 +            $this->raiseError("reached end of section $name but expecting end of " . $x["name"]."\n", NULL, PEAR_ERROR_DIE);
 +        }
 +
 +        if (isset($this->_sections[$name])) {
 +            $this->_sections[$name] += $microtime - $x["time"];
 +        } else {
 +            $this->_sections[$name] = $microtime - $x["time"];
 +        }
 +
 +        $parent = array_pop($this->_stack);
 +
 +      	if (isset($parent)) {
 +            if (isset($this->_subSectionsTime[$parent['name']])) {
 +                $this->_subSectionsTime[$parent['name']] += $microtime - $x['time'];
 +            } else {
 +                $this->_subSectionsTime[$parent['name']] = $microtime - $x['time'];
 +            }
 +
 +            array_push($this->_stack, $parent);
 +        }
 +    }
 +
 +    /**
 +     * Wrapper for microtime().
 +     *
 +     * @return float
 +     * @access private
 +     * @since  1.3.0
 +     */
 +    function _getMicrotime() {
 +        $microtime = explode(' ', microtime());
 +        return $microtime[1] . substr($microtime[0], 1);
 +    }
 +}
 diff --git a/buildscripts/Benchmark/Timer.php b/buildscripts/Benchmark/Timer.php new file mode 100644 index 00000000..d713e6b2 --- /dev/null +++ b/buildscripts/Benchmark/Timer.php @@ -0,0 +1,319 @@ +<?php
 +//
 +// +------------------------------------------------------------------------+
 +// | PEAR :: Benchmark                                                      |
 +// +------------------------------------------------------------------------+
 +// | Copyright (c) 2001-2006 Sebastian Bergmann <sb@sebastian-bergmann.de>. |
 +// +------------------------------------------------------------------------+
 +// | This source file is subject to the New BSD license, That is bundled    |
 +// | with this package in the file LICENSE, and is available through        |
 +// | the world-wide-web at                                                  |
 +// | http://www.opensource.org/licenses/bsd-license.php                     |
 +// | If you did not receive a copy of the new BSDlicense and are unable     |
 +// | to obtain it through the world-wide-web, please send a note to         |
 +// | license@php.net so we can mail you a copy immediately.                 |
 +// +------------------------------------------------------------------------+
 +//
 +// $Id: Timer.php,v 1.16 2006/03/01 13:41:39 matthias Exp $
 +//
 +
 +require_once 'PEAR.php';
 +
 +/**
 + * Provides timing and profiling information.
 + *
 + * Example 1: Automatic profiling start, stop, and output.
 + *
 + * <code>
 + * <?php
 + * require_once 'Benchmark/Timer.php';
 + *
 + * $timer = new Benchmark_Timer(TRUE);
 + * $timer->setMarker('Marker 1');
 + * ?>
 + * </code>
 + *
 + * Example 2: Manual profiling start, stop, and output.
 + *
 + * <code>
 + * <?php
 + * require_once 'Benchmark/Timer.php';
 + *
 + * $timer = new Benchmark_Timer();
 + * $timer->start();
 + * $timer->setMarker('Marker 1');
 + * $timer->stop();
 + *
 + * $timer->display(); // to output html formated
 + * // AND/OR :
 + * $profiling = $timer->getProfiling(); // get the profiler info as an associative array
 + * ?>
 + * </code>
 + *
 + * @author    Sebastian Bergmann <sb@sebastian-bergmann.de>
 + * @author    Ludovico Magnocavallo <ludo@sumatrasolutions.com>
 + * @copyright Copyright © 2002-2005 Sebastian Bergmann <sb@sebastian-bergmann.de>
 + * @license   http://www.php.net/license/3_0.txt The PHP License, Version 3.0
 + * @category  Benchmarking
 + * @package   Benchmark
 + */
 +class Benchmark_Timer extends PEAR {
 +    /**
 +     * Contains the markers.
 +     *
 +     * @var    array
 +     * @access private
 +     */
 +    var $markers = array();
 +
 +    /**
 +     * Auto-start and stop timer.
 +     *
 +     * @var    boolean
 +     * @access private
 +     */
 +    var $auto = FALSE;
 +
 +    /**
 +     * Max marker name length for non-html output.
 +     *
 +     * @var    integer
 +     * @access private
 +     */
 +    var $maxStringLength = 0;
 +
 +    /**
 +     * Constructor.
 +     *
 +     * @param  boolean $auto
 +     * @access public
 +     */
 +    function Benchmark_Timer($auto = FALSE) {
 +        $this->auto = $auto;
 +
 +        if ($this->auto) {
 +            $this->start();
 +        }
 +
 +        $this->PEAR();
 +    }
 +
 +    /**
 +     * Destructor.
 +     *
 +     * @access private
 +     */
 +    function _Benchmark_Timer() {
 +        if ($this->auto) {
 +            $this->stop();
 +            $this->display();
 +        }
 +    }
 +
 +    /**
 +     * Set "Start" marker.
 +     *
 +     * @see    setMarker(), stop()
 +     * @access public
 +     */
 +    function start() {
 +        $this->setMarker('Start');
 +    }
 +
 +    /**
 +     * Set "Stop" marker.
 +     *
 +     * @see    setMarker(), start()
 +     * @access public
 +     */
 +    function stop() {
 +        $this->setMarker('Stop');
 +    }
 +
 +    /**
 +     * Set marker.
 +     *
 +     * @param  string  $name Name of the marker to be set.
 +     * @see    start(), stop()
 +     * @access public
 +     */
 +    function setMarker($name) {
 +        $this->markers[$name] = $this->_getMicrotime();
 +    }
 +
 +    /**
 +     * Returns the time elapsed betweens two markers.
 +     *
 +     * @param  string  $start        start marker, defaults to "Start"
 +     * @param  string  $end          end marker, defaults to "Stop"
 +     * @return double  $time_elapsed time elapsed between $start and $end
 +     * @access public
 +     */
 +    function timeElapsed($start = 'Start', $end = 'Stop') {
 +        if ($end == 'Stop' && !isset($this->markers['Stop'])) {
 +            $this->markers['Stop'] = $this->_getMicrotime();
 +        }
 +
 +        if (extension_loaded('bcmath')) {
 +            return bcsub($this->markers[$end], $this->markers[$start], 6);
 +        } else {
 +            return $this->markers[$end] - $this->markers[$start];
 +        }
 +    }
 +
 +    /**
 +     * Returns profiling information.
 +     *
 +     * $profiling[x]['name']  = name of marker x
 +     * $profiling[x]['time']  = time index of marker x
 +     * $profiling[x]['diff']  = execution time from marker x-1 to this marker x
 +     * $profiling[x]['total'] = total execution time up to marker x
 +     *
 +     * @return array
 +     * @access public
 +     */
 +    function getProfiling() {
 +        $i = $total = 0;
 +        $result = array();
 +        $temp = reset($this->markers);
 +        $this->maxStringLength = 0;
 +
 +        foreach ($this->markers as $marker => $time) {
 +            if (extension_loaded('bcmath')) {
 +                $diff  = bcsub($time, $temp, 6);
 +                $total = bcadd($total, $diff, 6);
 +            } else {
 +                $diff  = $time - $temp;
 +                $total = $total + $diff;
 +            }
 +
 +            $result[$i]['name']  = $marker;
 +            $result[$i]['time']  = $time;
 +            $result[$i]['diff']  = $diff;
 +            $result[$i]['total'] = $total;
 +
 +            $this->maxStringLength = (strlen($marker) > $this->maxStringLength ? strlen($marker) + 1 : $this->maxStringLength);
 +
 +            $temp = $time;
 +            $i++;
 +        }
 +
 +        $result[0]['diff'] = '-';
 +        $result[0]['total'] = '-';
 +        $this->maxStringLength = (strlen('total') > $this->maxStringLength ? strlen('total') : $this->maxStringLength);
 +        $this->maxStringLength += 2;
 +
 +        return $result;
 +    }
 +
 +    /**
 +     * Return formatted profiling information.
 +     *
 +     * @param  boolean  $showTotal   Optionnaly includes total in output, default no
 +     * @param  string  $format   output format (auto, plain or html), default auto
 +     * @return string
 +     * @see    getProfiling()
 +     * @access public
 +     */
 +    function getOutput($showTotal = FALSE, $format = 'auto') {
 +        if ($format == 'auto') {
 +            if (function_exists('version_compare') &&
 +                version_compare(phpversion(), '4.1', 'ge'))
 +            {
 +                $format = isset($_SERVER['SERVER_PROTOCOL']) ? 'html' : 'plain';
 +            } else {
 +                global $HTTP_SERVER_VARS;
 +                $format = isset($HTTP_SERVER_VARS['SERVER_PROTOCOL']) ? 'html' : 'plain';
 +	    }
 +        }
 +
 +        $total  = $this->TimeElapsed();
 +        $result = $this->getProfiling();
 +        $dashes = '';
 +
 +        if ($format == 'html') {
 +            $out = '<table border="1">'."\n";
 +            $out .= '<tr><td> </td><td align="center"><b>time index</b></td><td align="center"><b>ex time</b></td><td align="center"><b>%</b></td>'.
 +            ($showTotal ?
 +              '<td align="center"><b>elapsed</b></td><td align="center"><b>%</b></td>'
 +               : '')."</tr>\n";
 +        } else {
 +            $dashes = $out = str_pad("\n",
 +                $this->maxStringLength + ($showTotal ? 70 : 45), '-', STR_PAD_LEFT);
 +            $out .= str_pad('marker', $this->maxStringLength) .
 +                    str_pad("time index", 22) .
 +                    str_pad("ex time", 16) .
 +                    str_pad("perct ", 8) .
 +                    ($showTotal ? ' '.str_pad("elapsed", 16)."perct" : '')."\n" .
 +                    $dashes;
 +        }
 +
 +        foreach ($result as $k => $v) {
 +            $perc = (($v['diff'] * 100) / $total);
 +            $tperc = (($v['total'] * 100) / $total);
 +
 +            if ($format == 'html') {
 +                $out .= "<tr><td><b>" . $v['name'] .
 +                       "</b></td><td>" . $v['time'] .
 +                       "</td><td>" . $v['diff'] .
 +                       "</td><td align=\"right\">" . number_format($perc, 2, '.', '') .
 +                       "%</td>".
 +                       ($showTotal ?
 +                            "<td>" . $v['total'] .
 +                            "</td><td align=\"right\">" .
 +                            number_format($tperc, 2, '.', '') .
 +                            "%</td>" : '').
 +                       "</tr>\n";
 +            } else {
 +                $out .= str_pad($v['name'], $this->maxStringLength, ' ') .
 +                        str_pad($v['time'], 22) .
 +                        str_pad($v['diff'], 14) .
 +                        str_pad(number_format($perc, 2, '.', '')."%",8, ' ', STR_PAD_LEFT) .
 +                        ($showTotal ? '   '.
 +                            str_pad($v['total'], 14) .
 +                            str_pad(number_format($tperc, 2, '.', '')."%",
 +                                             8, ' ', STR_PAD_LEFT) : '').
 +                        "\n";
 +            }
 +
 +            $out .= $dashes;
 +        }
 +
 +        if ($format == 'html') {
 +            $out .= "<tr style='background: silver;'><td><b>total</b></td><td>-</td><td>${total}</td><td>100.00%</td>".($showTotal ? "<td>-</td><td>-</td>" : "")."</tr>\n";
 +            $out .= "</table>\n";
 +        } else {
 +            $out .= str_pad('total', $this->maxStringLength);
 +            $out .= str_pad('-', 22);
 +            $out .= str_pad($total, 15);
 +            $out .= "100.00%\n";
 +            $out .= $dashes;
 +        }
 +
 +        return $out;
 +    }
 +
 +    /**
 +     * Prints the information returned by getOutput().
 +     *
 +     * @param  boolean  $showTotal   Optionnaly includes total in output, default no
 +     * @param  string  $format   output format (auto, plain or html), default auto
 +     * @see    getOutput()
 +     * @access public
 +     */
 +    function display($showTotal = FALSE, $format = 'auto') {
 +        print $this->getOutput($showTotal, $format);
 +    }
 +
 +    /**
 +     * Wrapper for microtime().
 +     *
 +     * @return float
 +     * @access private
 +     * @since  1.3.0
 +     */
 +    function _getMicrotime() {
 +        $microtime = explode(' ', microtime());
 +        return $microtime[1] . substr($microtime[0], 1);
 +    }
 +}
 diff --git a/buildscripts/Benchmark/doc/timer_example.php b/buildscripts/Benchmark/doc/timer_example.php new file mode 100644 index 00000000..93dd05c6 --- /dev/null +++ b/buildscripts/Benchmark/doc/timer_example.php @@ -0,0 +1,18 @@ +<?php
 +require '../Timer.php';
 +
 +function wait($amount) {
 +    for ($i=0; $i < $amount; $i++) {
 +        for ($i=0; $i < 100; $i++);
 +    }
 +}
 +// Pass the param "true" to constructor to automatically display the results
 +$timer = new Benchmark_Timer();
 +$timer->start();
 +wait(10);
 +$timer->setMarker('Mark1');
 +echo "Elapsed time between Start and Mark1: " .
 +      $timer->timeElapsed('Start', 'Mark1') . "\n";
 +wait(50);
 +$timer->stop();
 +$timer->display();
  | 
