Merge "Make DBAccessBase use DBConnRef, rename $wiki, and hide getLoadBalancer()"
[lhc/web/wiklou.git] / includes / profiler / ProfilerExcimer.php
1 <?php
2
3 class ProfilerExcimer extends Profiler {
4 /** @var ExcimerProfiler */
5 private $cpuProf;
6 /** @var ExcimerProfiler */
7 private $realProf;
8 private $period;
9
10 /**
11 * @param array $params Associative array of parameters:
12 * - period: The sampling period
13 * - maxDepth: The maximum stack depth collected
14 * - cpuProfiler: A pre-started ExcimerProfiler instance for CPU
15 * profiling of the entire request including configuration.
16 * - realProfiler: A pre-started ExcimerProfiler instance for wall
17 * clock profiling of the entire request.
18 */
19 public function __construct( array $params = [] ) {
20 parent::__construct( $params );
21
22 $this->period = $params['period'] ?? 0.01;
23 $maxDepth = $params['maxDepth'] ?? 100;
24
25 if ( isset( $params['cpuProfiler'] ) ) {
26 $this->cpuProf = $params['cpuProfiler'];
27 } else {
28 $this->cpuProf = new ExcimerProfiler;
29 $this->cpuProf->setEventType( EXCIMER_CPU );
30 $this->cpuProf->setPeriod( $this->period );
31 $this->cpuProf->setMaxDepth( $maxDepth );
32 $this->cpuProf->start();
33 }
34
35 if ( isset( $params['realProfiler'] ) ) {
36 $this->realProf = $params['realProfiler'];
37 } else {
38 $this->realProf = new ExcimerProfiler;
39 $this->realProf->setEventType( EXCIMER_REAL );
40 $this->realProf->setPeriod( $this->period );
41 $this->realProf->setMaxDepth( $maxDepth );
42 $this->realProf->start();
43 }
44 }
45
46 public function scopedProfileIn( $section ) {
47 }
48
49 public function close() {
50 $this->cpuProf->stop();
51 $this->realProf->stop();
52 }
53
54 public function getFunctionStats() {
55 $this->close();
56 $cpuStats = $this->cpuProf->getLog()->aggregateByFunction();
57 $realStats = $this->realProf->getLog()->aggregateByFunction();
58 $allNames = array_keys( $realStats + $cpuStats );
59 $cpuSamples = $this->cpuProf->getLog()->getEventCount();
60 $realSamples = $this->realProf->getLog()->getEventCount();
61
62 $resultStats = [ [
63 'name' => '-total',
64 'calls' => 1,
65 'memory' => 0,
66 '%memory' => 0,
67 'min_real' => 0,
68 'max_real' => 0,
69 'cpu' => $cpuSamples * $this->period * 1000,
70 '%cpu' => 100,
71 'real' => $realSamples * $this->period * 1000,
72 '%real' => 100,
73 ] ];
74
75 foreach ( $allNames as $funcName ) {
76 $cpuEntry = $cpuStats[$funcName] ?? false;
77 $realEntry = $realStats[$funcName] ?? false;
78 $resultEntry = [
79 'name' => $funcName,
80 'calls' => 0,
81 'memory' => 0,
82 '%memory' => 0,
83 'min_real' => 0,
84 'max_real' => 0,
85 ];
86
87 if ( $cpuEntry ) {
88 $resultEntry['cpu'] = $cpuEntry['inclusive'] * $this->period * 1000;
89 $resultEntry['%cpu'] = $cpuEntry['inclusive'] / $cpuSamples * 100;
90 } else {
91 $resultEntry['cpu'] = 0;
92 $resultEntry['%cpu'] = 0;
93 }
94 if ( $realEntry ) {
95 $resultEntry['real'] = $realEntry['inclusive'] * $this->period * 1000;
96 $resultEntry['%real'] = $realEntry['inclusive'] / $realSamples * 100;
97 } else {
98 $resultEntry['real'] = 0;
99 $resultEntry['%real'] = 0;
100 }
101
102 $resultStats[] = $resultEntry;
103 }
104 return $resultStats;
105 }
106
107 public function getOutput() {
108 $this->close();
109 $cpuLog = $this->cpuProf->getLog();
110 $realLog = $this->realProf->getLog();
111 $cpuStats = $cpuLog->aggregateByFunction();
112 $realStats = $realLog->aggregateByFunction();
113 $allNames = array_keys( $cpuStats + $realStats );
114 $cpuSamples = $cpuLog->getEventCount();
115 $realSamples = $realLog->getEventCount();
116
117 $result = '';
118
119 $titleFormat = "%-70s %10s %11s %10s %11s %10s %11s %10s %11s\n";
120 $statsFormat = "%-70s %10d %10.1f%% %10d %10.1f%% %10d %10.1f%% %10d %10.1f%%\n";
121 $result .= sprintf( $titleFormat,
122 'Name',
123 'CPU incl', 'CPU incl%', 'CPU self', 'CPU self%',
124 'Real incl', 'Real incl%', 'Real self', 'Real self%'
125 );
126
127 foreach ( $allNames as $funcName ) {
128 $realEntry = $realStats[$funcName] ?? false;
129 $cpuEntry = $cpuStats[$funcName] ?? false;
130 $realIncl = $realEntry ? $realEntry['inclusive'] : 0;
131 $realSelf = $realEntry ? $realEntry['self'] : 0;
132 $cpuIncl = $cpuEntry ? $cpuEntry['inclusive'] : 0;
133 $cpuSelf = $cpuEntry ? $cpuEntry['self'] : 0;
134 $result .= sprintf( $statsFormat,
135 $funcName,
136 $cpuIncl * $this->period * 1000,
137 $cpuIncl == 0 ? 0 : $cpuIncl / $cpuSamples * 100,
138 $cpuSelf * $this->period * 1000,
139 $cpuSelf == 0 ? 0 : $cpuSelf / $cpuSamples * 100,
140 $realIncl * $this->period * 1000,
141 $realIncl == 0 ? 0 : $realIncl / $realSamples * 100,
142 $realSelf * $this->period * 1000,
143 $realSelf == 0 ? 0 : $realSelf / $realSamples * 100
144 );
145 }
146
147 return $result;
148 }
149 }