code profiling?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

code profiling?

Post by Luke »

I have become very interested in Magento Commerce recently for several reasons.
  1. I hate Miva Merchant and I'm dying to use something else
    I plan on eventually devoting more time to DevNetStore and so it will be good to fully understand a project so similar
    This is the first REAL application I've seen to utilize the Zend Framework to its full extent and it seems to be pretty well written and thought out
(How come numbered lists don't work on this site?)

While perusing the source code, I have found a number of rather interesting things. The first being what is called code profiling. I do not understand what it does in the least. Anybody?

Code: Select all

<?php
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * @category   Varien
 * @package    Varien_Profiler
 * @copyright  Copyright (c) 2004-2007 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */


class Varien_Profiler
{

    /**
     * Timers for code profiling
     *
     * @var array
     */
    static private $_timers = array();
    static private $_enabled = false;
    static private $_memory_get_usage = false;
    
    public static function enable()
    {
        self::$_enabled = true;
        self::$_memory_get_usage = function_exists('memory_get_usage');
    }
    
    public static function disable()
    {
        self::$_enabled = false;
    }
    
    public static function reset($timerName)
    {
        self::$_timers[$timerName] = array(
        	'start'=>false, 
        	'count'=>0, 
        	'sum'=>0,
        	'realmem'=>0,
        	'emalloc'=>0,
        );
    }
    
    public static function resume($timerName)
    {
        if (!self::$_enabled) {
            return;
        }
        
        if (empty(self::$_timers[$timerName])) {
            self::reset($timerName);
        }
        if (self::$_memory_get_usage) {
        	self::$_timers[$timerName]['realmem_start'] = memory_get_usage(true);
        	self::$_timers[$timerName]['emalloc_start'] = memory_get_usage();
        }
        self::$_timers[$timerName]['start'] = microtime(true);
        self::$_timers[$timerName]['count'] ++;
    }
    
    public static function start($timerName)
    {
        self::resume($timerName);
    }
    
    public static function pause($timerName)
    {
        if (!self::$_enabled) {
            return;
        }
        
        if (empty(self::$_timers[$timerName])) {
            self::reset($timerName);
        }
        if (false!==self::$_timers[$timerName]['start']) {
            self::$_timers[$timerName]['sum'] += microtime(true)-self::$_timers[$timerName]['start'];
            self::$_timers[$timerName]['start'] = false;
            if (self::$_memory_get_usage) {
	            self::$_timers[$timerName]['realmem'] += memory_get_usage(true)-self::$_timers[$timerName]['realmem_start'];
    	        self::$_timers[$timerName]['emalloc'] += memory_get_usage()-self::$_timers[$timerName]['emalloc_start'];
            }
        }
    }
    
    public static function stop($timerName)
    {
        self::pause($timerName);
    }
    
    public static function fetch($timerName, $key='sum')
    {
        if (empty(self::$_timers[$timerName])) {
            return false;
        } elseif (empty($key)) {
            return self::$_timers[$timerName];
        }
        switch ($key) {
            case 'sum':
                $sum = self::$_timers[$timerName]['sum'];
                if (self::$_timers[$timerName]['start']!==false) {
                    $sum += microtime(true)-self::$_timers[$timerName]['start'];
                }
                return $sum;
                
            case 'count':
                $count = self::$_timers[$timerName]['count'];
                return $count;
             
            case 'realmem':
            	if (!isset(self::$_timers[$timerName]['realmem'])) {
            		self::$_timers[$timerName]['realmem'] = -1;
            	}
            	return self::$_timers[$timerName]['realmem'];
            	
            case 'emalloc':
            	if (!isset(self::$_timers[$timerName]['emalloc'])) {
            		self::$_timers[$timerName]['emalloc'] = -1;
            	}
            	return self::$_timers[$timerName]['emalloc'];
           
            default:
                if (!empty(self::$_timers[$timerName][$key])) {
                    return self::$_timers[$timerName][$key];
                }
        }
        return false;
    }
    
    public static function getTimers()
    {
        return self::$_timers;
    }

    /**
     * Output SQl Zend_Db_Profiler
     *
     */
    public static function getSqlProfiler($res) {
        if(!$res){
            return '';
        }
        $out = '';
        $profiler = $res->getProfiler();
        if($profiler->getEnabled()) {
            $totalTime    = $profiler->getTotalElapsedSecs();
            $queryCount   = $profiler->getTotalNumQueries();
            $longestTime  = 0;
            $longestQuery = null;

            foreach ($profiler->getQueryProfiles() as $query) {
                if ($query->getElapsedSecs() > $longestTime) {
                    $longestTime  = $query->getElapsedSecs();
                    $longestQuery = $query->getQuery();
                }
            }

            $out .= 'Executed ' . $queryCount . ' queries in ' . $totalTime . ' seconds' . "<br>";
            $out .= 'Average query length: ' . $totalTime / $queryCount . ' seconds' . "<br>";
            $out .= 'Queries per second: ' . $queryCount / $totalTime . "<br>";
            $out .= 'Longest query length: ' . $longestTime . "<br>";
            $out .= 'Longest query: <br>' . $longestQuery . "<hr>";
        }
        return $out;
    }
}
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

It looks like some fancy timing code that also track memory usage along with times. The last function creates a print-out of data from the Zend Db Profiler.
(#10850)
Post Reply