a418d308c3b359cc154b760f199c73c594a88b61
[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 raw and collated breakdown 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 method calls
75 * - elapsed : real time ellapsed (ms)
76 * - percent : percent real time
77 * - memory : memory used (bytes)
78 * - min : min real time of all calls (ms)
79 * - max : max real time of all calls (ms)
80 */
81 public function getFunctionStats() {
82 $data = $this->profiler->getRawData();
83
84 $memoryTotal = 0;
85 $elapsedTotal = 0;
86 foreach ( $data as $item ) {
87 $memoryTotal += $item['memory'];
88 $elapsedTotal += $item['elapsed'];
89 }
90
91 foreach ( $data as &$item ) {
92 $item['percent'] = $item['elapsed'] / $elapsedTotal * 100;
93 }
94 unset( $item );
95
96 $data[] = array(
97 'name' => '-total',
98 'calls' => 1,
99 'elapsed' => $elapsedTotal,
100 'percent' => 100,
101 'memory' => $memoryTotal,
102 'min' => $elapsedTotal,
103 'max' => $elapsedTotal
104 );
105
106 return $data;
107 }
108 }