<?php
/**
* Class Tracker
* {"file":"tick.php","line":66,"type":"memory","diff":"32MB"}
* {"file":"tick.php","line":70,"type":"time","diff":"1s"}
* {"file":"tick.php","line":76,"type":"execution","times":10000}
*/
class Tracker{
protected $executionLimit;
protected $memoryLimit;
protected $timeLimit;
protected $timeStart;
protected $memoryStart;
protected $executionMap;
protected $badSmells = [];
public function __construct($executionLimit=100, $memoryLimit=1024*1024, $timeLimit=100){
$this->executionLimit = intval($executionLimit);
$this->memoryLimit = intval($memoryLimit);
$this->timeLimit = intval($timeLimit);
$this->memoryStart = memory_get_usage();
}
public function startTrack(){
declare (ticks = 1);
return ($this->timeLimit > 0 || $this->memoryLimit > 0 || $this->executionLimit > 0)
&& register_tick_function([$this, 'tickHook']);
}
public function terminalTrack(){
if(!empty($this->badSmells)){
foreach ($this->badSmells as $bs) {
echo json_encode($bs).PHP_EOL;
}
}
}
public function tickHook(){
$trace = debug_backtrace(1);
$key = $trace[0]['file'].'_'.$trace[0]['line'];
if($this->timeLimit > 0){
$nowTime = microtime(1) * 1000;
if($this->timeStart < 1){
$this->timeStart = $nowTime;
}else{
$timeDiff = $nowTime - $this->timeStart;
if($timeDiff >= $this->timeLimit){
$this->badSmells[$key.'_time'] = ['file'=>$trace[0]['file'], 'line'=>$trace[0]['line'], 'type'=>'time', 'diff'=>round($timeDiff/1000, 1).'s'];
$this->timeStart = 0;
}
}
}
if($this->memoryLimit > 0){
$nowMemory = memory_get_usage();
$memoryDiff = $nowMemory - $this->memoryStart;
if($memoryDiff >= $this->memoryLimit){
$this->badSmells[$key.'_memory'] = ['file'=>$trace[0]['file'], 'line'=>$trace[0]['line'], 'type'=>'memory', 'diff'=>round($memoryDiff/1024/1024, 1).'MB'];
}
$this->memoryStart = $nowMemory;
}
if($this->executionLimit > 0){
$this->executionMap[$key]++;
if($this->executionMap[$key] >= $this->executionLimit){
$this->badSmells[$key.'_execution'] = ['file'=>$trace[0]['file'], 'line'=>$trace[0]['line'], 'type'=>'execution', 'times'=>$this->executionMap[$key]];
}
}
}
}
function f1_memory($n){
$data = array_fill(0, $n, 0);
}
function f2_time(){
sleep(1);
}
function f3_execute(){
$sum = 0;
for($i=0; $i<10000; $i++){
$sum += $i;
}
return $sum;
}
$tracker = new Tracker();
$tracker->startTrack();
f1_memory(1000000);
f2_time();
f3_execute();
$tracker->terminalTrack();
网友评论