3 class ProfilerExcimer
extends Profiler
{
9 * @param array $params Associative array of parameters:
10 * - period: The sampling period
11 * - maxDepth: The maximum stack depth collected
12 * - cpuProfiler: A pre-started ExcimerProfiler instance for CPU
13 * profiling of the entire request including configuration.
14 * - realProfiler: A pre-started ExcimerProfiler instance for wall
15 * clock profiling of the entire request.
17 public function __construct( array $params = [] ) {
18 parent
::__construct( $params );
20 $this->period
= $params['period'] ??
0.01;
21 $maxDepth = $params['maxDepth'] ??
100;
23 if ( isset( $params['cpuProfiler'] ) ) {
24 $this->cpuProf
= $params['cpuProfiler'];
26 $this->cpuProf
= new ExcimerProfiler
;
27 $this->cpuProf
->setEventType( EXCIMER_CPU
);
28 $this->cpuProf
->setPeriod( $this->period
);
29 $this->cpuProf
->setMaxDepth( $maxDepth );
30 $this->cpuProf
->start();
33 if ( isset( $params['realProfiler'] ) ) {
34 $this->realProf
= $params['realProfiler'];
36 $this->realProf
= new ExcimerProfiler
;
37 $this->realProf
->setEventType( EXCIMER_REAL
);
38 $this->realProf
->setPeriod( $this->period
);
39 $this->realProf
->setMaxDepth( $maxDepth );
40 $this->realProf
->start();
44 public function scopedProfileIn( $section ) {
47 public function close() {
48 $this->cpuProf
->stop();
49 $this->realProf
->stop();
52 public function getFunctionStats() {
54 $cpuStats = $this->cpuProf
->getLog()->aggregateByFunction();
55 $realStats = $this->realProf
->getLog()->aggregateByFunction();
56 $allNames = array_keys( $realStats +
$cpuStats );
57 $cpuSamples = $this->cpuProf
->getLog()->getEventCount();
58 $realSamples = $this->realProf
->getLog()->getEventCount();
67 'cpu' => $cpuSamples * $this->period
* 1000,
69 'real' => $realSamples * $this->period
* 1000,
73 foreach ( $allNames as $funcName ) {
74 $cpuEntry = $cpuStats[$funcName] ??
false;
75 $realEntry = $realStats[$funcName] ??
false;
86 $resultEntry['cpu'] = $cpuEntry['inclusive'] * $this->period
* 1000;
87 $resultEntry['%cpu'] = $cpuEntry['inclusive'] / $cpuSamples * 100;
89 $resultEntry['cpu'] = 0;
90 $resultEntry['%cpu'] = 0;
93 $resultEntry['real'] = $realEntry['inclusive'] * $this->period
* 1000;
94 $resultEntry['%real'] = $realEntry['inclusive'] / $realSamples * 100;
96 $resultEntry['real'] = 0;
97 $resultEntry['%real'] = 0;
100 $resultStats[] = $resultEntry;
105 public function getOutput() {
107 $cpuLog = $this->cpuProf
->getLog();
108 $realLog = $this->realProf
->getLog();
109 $cpuStats = $cpuLog->aggregateByFunction();
110 $realStats = $realLog->aggregateByFunction();
111 $allNames = array_keys( $cpuStats +
$realStats );
112 $cpuSamples = $cpuLog->getEventCount();
113 $realSamples = $realLog->getEventCount();
117 $titleFormat = "%-70s %10s %11s %10s %11s %10s %11s %10s %11s\n";
118 $statsFormat = "%-70s %10d %10.1f%% %10d %10.1f%% %10d %10.1f%% %10d %10.1f%%\n";
119 $result .= sprintf( $titleFormat,
121 'CPU incl', 'CPU incl%', 'CPU self', 'CPU self%',
122 'Real incl', 'Real incl%', 'Real self', 'Real self%'
125 foreach ( $allNames as $funcName ) {
126 $realEntry = $realStats[$funcName] ??
false;
127 $cpuEntry = $cpuStats[$funcName] ??
false;
128 $realIncl = $realEntry ?
$realEntry['inclusive'] : 0;
129 $realSelf = $realEntry ?
$realEntry['self'] : 0;
130 $cpuIncl = $cpuEntry ?
$cpuEntry['inclusive'] : 0;
131 $cpuSelf = $cpuEntry ?
$cpuEntry['self'] : 0;
132 $result .= sprintf( $statsFormat,
134 $cpuIncl * $this->period
* 1000,
135 $cpuIncl == 0 ?
0 : $cpuIncl / $cpuSamples * 100,
136 $cpuSelf * $this->period
* 1000,
137 $cpuSelf == 0 ?
0 : $cpuSelf / $cpuSamples * 100,
138 $realIncl * $this->period
* 1000,
139 $realIncl == 0 ?
0 : $realIncl / $realSamples * 100,
140 $realSelf * $this->period
* 1000,
141 $realSelf == 0 ?
0 : $realSelf / $realSamples * 100