Refactor profiling output from profiling
[lhc/web/wiklou.git] / includes / profiler / SectionProfiler.php
1 <?php
2 /**
3 * Arbitrary section name based PHP profiling.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup Profiler
22 * @author Aaron Schulz
23 */
24
25 /**
26 * Custom PHP profiler for parser/DB type section names that xhprof/xdebug can't handle
27 *
28 * @TODO: refactor implementation by moving Profiler code to here when non-automatic
29 * profiler support is dropped.
30 *
31 * @since 1.25
32 */
33 class SectionProfiler {
34 /** @var ProfilerStandard */
35 protected $profiler;
36
37 public function __construct() {
38 // This does *not* care about PHP request start time
39 $this->profiler = new ProfilerStandard( array( 'initTotal' => false ) );
40 }
41
42 /**
43 * @param string $section
44 * @return ScopedCallback
45 */
46 public function scopedProfileIn( $section ) {
47 $profiler = $this->profiler;
48 $sc = new ScopedCallback( function() use ( $profiler, $section ) {
49 $profiler->profileOut( $section );
50 } );
51 $profiler->profileIn( $section );
52
53 return $sc;
54 }
55
56 /**
57 * @param ScopedCallback $section
58 */
59 public function scopedProfileOut( ScopedCallback &$section ) {
60 $section = null;
61 }
62
63 /**
64 * Get the aggregated inclusive profiling data for each method
65 *
66 * The percent time for each time is based on the current "total" time
67 * used is based on all methods so far. This method can therefore be
68 * called several times in between several profiling calls without the
69 * delays in usage of the profiler skewing the results. A "-total" entry
70 * is always included in the results.
71 *
72 * @return array List of method entries arrays, each having:
73 * - name : method name
74 * - calls : the number of invoking calls
75 * - real : real time ellapsed (ms)
76 * - %real : percent real time
77 * - cpu : real time ellapsed (ms)
78 * - %cpu : percent real time
79 * - memory : memory used (bytes)
80 * - %memory : percent memory used
81 */
82 public function getFunctionStats() {
83 $data = $this->profiler->getFunctionStats();
84
85 $cpuTotal = 0;
86 $memoryTotal = 0;
87 $elapsedTotal = 0;
88 foreach ( $data as $item ) {
89 $memoryTotal += $item['memory'];
90 $elapsedTotal += $item['real'];
91 $cpuTotal += $item['cpu'];
92 }
93
94 foreach ( $data as &$item ) {
95 $item['%cpu'] = $item['cpu'] ? $item['cpu'] / $cpuTotal * 100 : 0;
96 $item['%real'] = $elapsedTotal ? $item['real'] / $elapsedTotal * 100 : 0;
97 $item['%memory'] = $item['memory'] ? $item['memory'] / $memoryTotal * 100 : 0;
98 }
99 unset( $item );
100
101 $data[] = array(
102 'name' => '-total',
103 'calls' => 1,
104 'real' => $elapsedTotal,
105 '%real' => 100,
106 'memory' => $memoryTotal,
107 '%memory' => 100,
108 );
109
110 return $data;
111 }
112 }