Merge "Follow-up I2266ec0: Mark new method as an internal"
[lhc/web/wiklou.git] / includes / profiler / ProfilerExcimer.php
1 <?php
2
3 class ProfilerExcimer extends Profiler {
4 private $cpuProf;
5 private $realProf;
6 private $period;
7
8 public function __construct( array $params = [] ) {
9 parent::__construct( $params );
10
11 $this->period = $params['period'] ?? 0.01;
12 $maxDepth = $params['maxDepth'] ?? 100;
13
14 $this->cpuProf = new ExcimerProfiler;
15 $this->cpuProf->setEventType( EXCIMER_CPU );
16 $this->cpuProf->setPeriod( $this->period );
17 $this->cpuProf->setMaxDepth( $maxDepth );
18
19 $this->realProf = new ExcimerProfiler;
20 $this->realProf->setEventType( EXCIMER_REAL );
21 $this->realProf->setPeriod( $this->period );
22 $this->realProf->setMaxDepth( $maxDepth );
23
24 $this->cpuProf->start();
25 $this->realProf->start();
26 }
27
28 public function scopedProfileIn( $section ) {
29 }
30
31 public function close() {
32 $this->cpuProf->stop();
33 $this->realProf->stop();
34 }
35
36 public function getFunctionStats() {
37 $this->close();
38 $cpuStats = $this->cpuProf->getLog()->aggregateByFunction();
39 $realStats = $this->realProf->getLog()->aggregateByFunction();
40 $allNames = array_keys( $realStats + $cpuStats );
41 $cpuSamples = $this->cpuProf->getLog()->getEventCount();
42 $realSamples = $this->realProf->getLog()->getEventCount();
43
44 $resultStats = [ [
45 'name' => '-total',
46 'calls' => 1,
47 'memory' => 0,
48 '%memory' => 0,
49 'min_real' => 0,
50 'max_real' => 0,
51 'cpu' => $cpuSamples * $this->period * 1000,
52 '%cpu' => 100,
53 'real' => $realSamples * $this->period * 1000,
54 '%real' => 100,
55 ] ];
56
57 foreach ( $allNames as $funcName ) {
58 $cpuEntry = $cpuStats[$funcName] ?? false;
59 $realEntry = $realStats[$funcName] ?? false;
60 $resultEntry = [
61 'name' => $funcName,
62 'calls' => 0,
63 'memory' => 0,
64 '%memory' => 0,
65 'min_real' => 0,
66 'max_real' => 0,
67 ];
68
69 if ( $cpuEntry ) {
70 $resultEntry['cpu'] = $cpuEntry['inclusive'] * $this->period * 1000;
71 $resultEntry['%cpu'] = $cpuEntry['inclusive'] / $cpuSamples * 100;
72 } else {
73 $resultEntry['cpu'] = 0;
74 $resultEntry['%cpu'] = 0;
75 }
76 if ( $realEntry ) {
77 $resultEntry['real'] = $realEntry['inclusive'] * $this->period * 1000;
78 $resultEntry['%real'] = $realEntry['inclusive'] / $realSamples * 100;
79 } else {
80 $resultEntry['real'] = 0;
81 $resultEntry['%real'] = 0;
82 }
83
84 $resultStats[] = $resultEntry;
85 }
86 return $resultStats;
87 }
88
89 public function getOutput() {
90 $this->close();
91 $cpuLog = $this->cpuProf->getLog();
92 $realLog = $this->realProf->getLog();
93 $cpuStats = $cpuLog->aggregateByFunction();
94 $realStats = $realLog->aggregateByFunction();
95 $allNames = array_keys( $cpuStats + $realStats );
96 $cpuSamples = $cpuLog->getEventCount();
97 $realSamples = $realLog->getEventCount();
98
99 $result = '';
100
101 $titleFormat = "%-70s %10s %11s %10s %11s %10s %11s %10s %11s\n";
102 $statsFormat = "%-70s %10d %10.1f%% %10d %10.1f%% %10d %10.1f%% %10d %10.1f%%\n";
103 $result .= sprintf( $titleFormat,
104 'Name',
105 'CPU incl', 'CPU incl%', 'CPU self', 'CPU self%',
106 'Real incl', 'Real incl%', 'Real self', 'Real self%'
107 );
108
109 foreach ( $allNames as $funcName ) {
110 $realEntry = $realStats[$funcName] ?? false;
111 $cpuEntry = $cpuStats[$funcName] ?? false;
112 $realIncl = $realEntry ? $realEntry['inclusive'] : 0;
113 $realSelf = $realEntry ? $realEntry['self'] : 0;
114 $cpuIncl = $cpuEntry ? $cpuEntry['inclusive'] : 0;
115 $cpuSelf = $cpuEntry ? $cpuEntry['self'] : 0;
116 $result .= sprintf( $statsFormat,
117 $funcName,
118 $cpuIncl * $this->period * 1000,
119 $cpuIncl == 0 ? 0 : $cpuIncl / $cpuSamples * 100,
120 $cpuSelf * $this->period * 1000,
121 $cpuSelf == 0 ? 0 : $cpuSelf / $cpuSamples * 100,
122 $realIncl * $this->period * 1000,
123 $realIncl == 0 ? 0 : $realIncl / $realSamples * 100,
124 $realSelf * $this->period * 1000,
125 $realSelf == 0 ? 0 : $realSelf / $realSamples * 100
126 );
127 }
128
129 return $result;
130 }
131 }