41define(
'MW_NO_SESSION', 1 );
43define(
'MW_ENTRY_POINT',
'profileinfo' );
45ini_set(
'zlib.output_compression',
'off' );
47require __DIR__ .
'/includes/WebStart.php';
49header(
'Content-Type: text/html; charset=utf-8' );
55 <meta charset=
"UTF-8" />
56 <title>Profiling data</title>
68 font: 14px/1.6 sans-serif;
78 text-decoration: none;
82 text-decoration: underline;
97 background-color: transparent;
98 border-collapse: collapse;
112 border-top: 1px solid #ddd;
120 vertical-align: bottom;
123 .table thead:first-child tr:first-child th,
124 .table thead:first-child tr:first-child td {
128 .table tbody + tbody {
129 border-top: 2px solid #ddd;
133 .table-condensed td {
137 .table-striped tbody tr:nth-child(odd) td,
138 .table-striped tbody tr:nth-child(odd) th {
139 background-color: #f9f9f9;
142 .table-hover tbody tr:hover td,
143 .table-hover tbody tr:hover th {
144 background-color: #f5f5f5;
150 border-top: 1px solid #eee;
151 border-bottom: 1px solid #fff;
159 echo
'<p>Disabled</p>'
166if ( !
$dbr->tableExists(
'profiling' ) ) {
167 echo
'<p>No <code>profiling</code> table exists, so we can\'t show you anything.</p>'
168 .
'<p>If you want to log profiling data, enable <code>$wgProfiler[\'output\'] = \'db\'</code>'
169 .
' in LocalSettings.php and run <code>maintenance/update.php</code> to'
170 .
' create the profiling table.'
176if ( isset( $_REQUEST[
'expand'] ) ) {
177 foreach ( explode(
',', $_REQUEST[
'expand'] ) as $f ) {
198 $this->children = [];
202 $this->children[] = $child;
206 usort( $this->children,
'compare_point' );
210 $anchor = str_replace(
'"',
'', $this->
name() );
213 if (
count( $this->children ) ) {
215 $extet =
" <a id=\"{$anchor}\" href=\"{$url}#{$anchor}\">[+]</a>";
223 $e += [
$name => $ep ];
227 $extet =
" <a id=\"{$anchor}\" href=\"{$url}#{$anchor}\">[–]</a>";
232 <div style=
"margin-left: <?php echo (int)$indent; ?>em;">
233 <?php echo htmlspecialchars( str_replace(
',',
', ', $this->
name() ) ) . $extet ?>
237 <td
class=
"mw-profileinfo-timep"><?php echo @
wfPercent( $this->
time() / self::$totaltime * 100 ); ?></td>
238 <td
class=
"mw-profileinfo-memoryp"><?php echo @
wfPercent( $this->
memory() / self::$totalmemory * 100 ); ?></td>
239 <td
class=
"mw-profileinfo-count"><?php echo $this->
count(); ?></td>
240 <td
class=
"mw-profileinfo-cpr"><?php echo round( sprintf(
'%.2f', $this->
callsPerRequest() ), 2 ); ?></td>
241 <td
class=
"mw-profileinfo-tpc"><?php echo round( sprintf(
'%.2f', $this->
timePerCall() ), 2 ); ?></td>
242 <td
class=
"mw-profileinfo-mpc"><?php echo round( sprintf(
'%.2f', $this->
memoryPerCall() / 1024 ), 2 ); ?></td>
243 <td
class=
"mw-profileinfo-tpr"><?php echo @round( sprintf(
'%.2f', $this->
time() / self::$totalcount ), 2 ); ?></td>
244 <td
class=
"mw-profileinfo-mpr"><?php echo @round( sprintf(
'%.2f', $this->
memory() / self::$totalcount / 1024 ), 2 ); ?></td>
249 foreach ( $this->children as $child ) {
250 $child->display(
$expand, $indent + 2 );
268 return $this->memory;
297 return sprintf(
'%5.02f', $this->
time );
308 return strcmp( $a->
name(), $b->
name() );
316 case 'time_per_call':
318 case 'memory_per_call':
320 case 'calls_per_req':
324 case 'memory_per_req':
329$sorts = [
'time',
'memory',
'count',
'calls_per_req',
'name',
330 'time_per_call',
'memory_per_call',
'time_per_req',
'memory_per_req' ];
332if ( isset( $_REQUEST[
'sort'] ) && in_array( $_REQUEST[
'sort'],
$sorts ) ) {
333 $sort = $_REQUEST[
'sort'];
341 [
'ORDER BY' =>
'pf_name ASC' ]
347<form method=
"get" action=
"profileinfo.php">
349 <input type=
"text" name=
"filter" value=
"<?php echo htmlspecialchars( $filter ); ?>">
350 <input type=
"hidden" name=
"sort" value=
"<?php echo htmlspecialchars( $sort ); ?>">
351 <input type=
"hidden" name=
"expand" value=
"<?php
352 echo htmlspecialchars( implode( ",
", array_keys( $expand ) ) );
354 <input type=
"submit" value=
"Filter">
358<table
class=
"mw-profileinfo-table table table-striped table-hover">
362 echo getEscapedProfileUrl( false, 'name' );
365 echo getEscapedProfileUrl( false, 'time' );
366 ?>">Time (%)</a></th>
368 echo getEscapedProfileUrl( false, 'memory' );
369 ?>">Memory (%)</a></th>
371 echo getEscapedProfileUrl( false, 'count' );
374 echo getEscapedProfileUrl( false, 'calls_per_req' );
375 ?>">Calls/req</a></th>
377 echo getEscapedProfileUrl( false, 'time_per_call' );
380 echo getEscapedProfileUrl( false, 'memory_per_call' );
383 echo getEscapedProfileUrl( false, 'time_per_req' );
386 echo getEscapedProfileUrl( false, 'memory_per_req' );
400 if ( $_expand ===
false ) {
404 return htmlspecialchars(
407 'filter' => $_filter ?:
$filter,
408 'sort' => $_sort ?:
$sort,
409 'expand' => implode(
',', array_keys( $_expand ) )
420 foreach (
$res as $o ) {
421 $next =
new profile_point( $o->pf_name, $o->pf_count, $o->pf_time, $o->pf_memory );
422 if ( $next->name() ==
'-total' || $next->name() ==
'main()' ) {
427 if (
$last !==
false ) {
428 if ( preg_match(
'/^' . preg_quote(
$last->name(),
'/' ) .
'/', $next->name() ) ) {
429 $last->add_child( $next );
434 if ( preg_match(
'/^query: /', $next->name() ) || preg_match(
'/^query-m: /', $next->name() ) ) {
449 @usort(
$points,
'compare_point' );
451 foreach (
$points as $point ) {
$wgEnableProfileInfo
Allow the profileinfo.php entrypoint to be used.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfPercent( $nr, $acc=2, $round=true)
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
display( $expand, $indent=0.0)
__construct( $name, $count, $time, $memory)
if(isset( $_REQUEST['sort']) &&in_array( $_REQUEST['sort'], $sorts)) $res
compare_point(profile_point $a, profile_point $b)
getEscapedProfileUrl( $_filter=false, $_sort=false, $_expand=false)
if(! $wgEnableProfileInfo) $dbr
if(! $dbr->tableExists( 'profiling')) $expand