Location: PHPKode > projects > Agile Toolkit > atk4-atk4-addons-5a69383/performance/lib/Controller/Profiler.php
<?php
namespace performance;

class Controller_Profiler extends \AbstractController {

    public $timetable=array();
    public $curfunc=array();
    public $offset=0;
    public $profstart=null;
    public $calls=0;

    function init(){
        parent::init();
        $this->api->pr=$this;

        $this->profstart=time()+microtime();
        $this->start('everything else');
    }

    /** Returns microseconds since last call */
    function getOffset(){
        $t=time()+microtime()-$this->api->start_time;
        $res=$t-$this->offset;
        $this->offset=$t;
        return $res;
    }
    function logTime($activity,$limit=true){
        $this->timetable[$activity]['total']+=$this->getOffset();
        if(isset($limit) && $this->timetable[$activity]['total']>$limit)throw $this->exception('time limit');
    }

    function next($location=null,$ignore_fx=false){
        $this->stop(null,$ignore_fx);
        $this->start($location);
    }
    function getFlatStack(){
        $bt=debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
        $fx=array();
        foreach($bt as $row){
            if($row['class']=='performance\Controller_Profiler')continue;
            $fx[]=$row['class'].'::'.$row['function'].'()';
        }
        return join('  »  ',array_reverse($fx));
    }
    function start($location=null){
        if($this->curfunc)$this->logTime($this->curfunc[0][0]);
        else $this->getOffset();
        array_unshift($this->curfunc,array($location,$this->getFlatStack()));
        $this->timetable[$location]['calls']++;
        $this->logTime('Profiling');
    }
    function stop($limit=null,$ignore_fx=false){
        $this->calls++;
        if(!$this->curfunc){
            throw $this->exception('Stopping but wasn\'t started');
        }
        list($location,$stack)=array_shift($this->curfunc);
        $this->logTime($location,$limit);

        $newstack=$this->getFlatStack();
        if($stack!=$newstack && !$ignore_fx)throw $this->exception('Trace start and stop are in different functions. use stop(null,true); if that is desired')
            ->addMoreInfo('started_at',$stack)
            ->addMoreInfo('stopped_at',$newstack)
            ->addMoreInfo('location',$location)
            ;
        $this->logTime('Profiling');
    }
    function destroy(){
        $this->api->pr=new \Dummy();
        return parent::destroy();
    }
    function dump(){
        if($this->curfunc)var_Dump($this->curfunc);

        
        echo "Profiling period: ".($this->profstart-$this->api->start_time).' .. '.
            (time()+microtime()-$this->api->start_time).'<br/>';
        echo "Profiled (ms): <b>".round(1000*(time()+microtime()-$this->profstart
            -$this->timetable['Profiling']['total']
        ),2).'</b><br/>';

        uasort($this->timetable,function($l,$r){
            $l=$l['total'];///$l['calls'];
            $r=$r['total'];///$r['calls'];
            if($l>$r)return -1;
            if($l<$r)return 1;
        });

        $x=0;
        foreach($this->timetable as $activity=>$detail){
            if($activity=='Profiling'){
                $activity='<font color="gray">'.$activity.'</font>';
                $detail['calls']=$this->calls*2;
            }
            $x+=$detail['total'];
            echo '+'.number_format($detail['total']/*/$detail['calls']*/*1000,2).' '.$activity.' x '.$detail['calls'].'<br/>';
        }
    }
    function __destruct(){
        $this->stop(null,true);
        $this->dump();
    }
}
Return current item: Agile Toolkit