MediaWiki
REL1_19
|
00001 <?php 00028 ini_set( 'zlib.output_compression', 'off' ); 00029 00030 $wgEnableProfileInfo = $wgProfileToDatabase = false; 00031 if ( isset( $_SERVER['MW_COMPILED'] ) ) { 00032 require ( 'phase3/includes/WebStart.php' ); 00033 } else { 00034 require ( dirname( __FILE__ ) . '/includes/WebStart.php' ); 00035 } 00036 00037 00038 header( 'Content-Type: text/html; charset=utf-8' ); 00039 00040 ?> 00041 <html> 00042 <head> 00043 <title>Profiling data</title> 00044 <style type="text/css"> 00045 th { 00046 text-align: left; 00047 border-bottom: solid 1px black; 00048 } 00049 00050 th, td { 00051 padding-left: 0.5em; 00052 padding-right: 0.5em; 00053 } 00054 00055 td.timep, td.memoryp, td.count, td.cpr, td.tpc, td.mpc, td.tpr, td.mpr { 00056 text-align: right; 00057 } 00058 td.timep, td.tpc, td.tpr { 00059 background-color: #fffff0; 00060 } 00061 td.memoryp, td.mpc, td.mpr { 00062 background-color: #f0f8ff; 00063 } 00064 td.count, td,cpr { 00065 background-color: #f0fff0; 00066 } 00067 td.name { 00068 background-color: #f9f9f9; 00069 } 00070 </style> 00071 </head> 00072 <body> 00073 <?php 00074 00075 if ( !$wgEnableProfileInfo ) { 00076 echo "<p>Disabled</p>\n"; 00077 echo "</body></html>"; 00078 exit( 1 ); 00079 } 00080 00081 $dbr = wfGetDB( DB_SLAVE ); 00082 00083 if( !$dbr->tableExists( 'profiling' ) ) { 00084 echo "<p>No 'profiling' table exists, so we can't show you anything.</p>\n"; 00085 echo "<p>If you want to log profiling data, create the table using " 00086 . "<tt>maintenance/archives/patch-profiling.sql</tt> and enable " 00087 . "<tt>\$wgProfileToDatabase</tt>.</p>\n"; 00088 echo "</body></html>"; 00089 exit( 1 ); 00090 } 00091 00092 $expand = array(); 00093 if ( isset( $_REQUEST['expand'] ) ) 00094 foreach( explode( ',', $_REQUEST['expand'] ) as $f ) 00095 $expand[$f] = true; 00096 00097 class profile_point { 00098 var $name; 00099 var $count; 00100 var $time; 00101 var $children; 00102 00103 static $totaltime, $totalmemory, $totalcount; 00104 00105 function __construct( $name, $count, $time, $memory ) { 00106 $this->name = $name; 00107 $this->count = $count; 00108 $this->time = $time; 00109 $this->memory = $memory; 00110 $this->children = array(); 00111 } 00112 00113 function add_child( $child ) { 00114 $this->children[] = $child; 00115 } 00116 00117 function display( $expand, $indent = 0.0 ) { 00118 usort( $this->children, 'compare_point' ); 00119 00120 $ex = isset( $expand[$this->name()] ); 00121 00122 if ( !$ex ) { 00123 if ( count( $this->children ) ) { 00124 $url = getEscapedProfileUrl( false, false, $expand + array( $this->name() => true ) ); 00125 $extet = " <a href=\"$url\">[+]</a>"; 00126 } else { 00127 $extet = ''; 00128 } 00129 } else { 00130 $e = array(); 00131 foreach ( $expand as $name => $ep ) { 00132 if ( $name != $this->name() ) { 00133 $e += array( $name => $ep ); 00134 } 00135 } 00136 00137 $extet = " <a href=\"" . getEscapedProfileUrl( false, false, $e ) . "\">[–]</a>"; 00138 } 00139 ?> 00140 <tr> 00141 <td class="name" style="padding-left: <?php echo $indent ?>em;"> 00142 <?php echo htmlspecialchars( $this->name() ) . $extet ?> 00143 </td> 00144 <td class="timep"><?php echo @wfPercent( $this->time() / self::$totaltime * 100 ) ?></td> 00145 <td class="memoryp"><?php echo @wfPercent( $this->memory() / self::$totalmemory * 100 ) ?></td> 00146 <td class="count"><?php echo $this->count() ?></td> 00147 <td class="cpr"><?php echo round( sprintf( '%.2f', $this->callsPerRequest() ), 2 ) ?></td> 00148 <td class="tpc"><?php echo round( sprintf( '%.2f', $this->timePerCall() ), 2 ) ?></td> 00149 <td class="mpc"><?php echo round( sprintf( '%.2f' ,$this->memoryPerCall() / 1024 ), 2 ) ?></td> 00150 <td class="tpr"><?php echo @round( sprintf( '%.2f', $this->time() / self::$totalcount ), 2 ) ?></td> 00151 <td class="mpr"><?php echo @round( sprintf( '%.2f' ,$this->memory() / self::$totalcount / 1024 ), 2 ) ?></td> 00152 </tr> 00153 <?php 00154 if ( $ex ) { 00155 foreach ( $this->children as $child ) { 00156 $child->display( $expand, $indent + 2 ); 00157 } 00158 } 00159 } 00160 00161 function name() { 00162 return $this->name; 00163 } 00164 00165 function count() { 00166 return $this->count; 00167 } 00168 00169 function time() { 00170 return $this->time; 00171 } 00172 00173 function memory() { 00174 return $this->memory; 00175 } 00176 00177 function timePerCall() { 00178 return @( $this->time / $this->count ); 00179 } 00180 00181 function memoryPerCall() { 00182 return @( $this->memory / $this->count ); 00183 } 00184 00185 function callsPerRequest() { 00186 return @( $this->count / self::$totalcount ); 00187 } 00188 00189 function timePerRequest() { 00190 return @( $this->time / self::$totalcount ); 00191 } 00192 00193 function memoryPerRequest() { 00194 return @( $this->memory / self::$totalcount ); 00195 } 00196 00197 function fmttime() { 00198 return sprintf( "%5.02f", $this->time ); 00199 } 00200 }; 00201 00202 function compare_point(profile_point $a, profile_point $b) { 00203 global $sort; 00204 switch ( $sort ) { 00205 case "name": 00206 return strcmp( $a->name(), $b->name() ); 00207 case "time": 00208 return $a->time() > $b->time() ? -1 : 1; 00209 case "memory": 00210 return $a->memory() > $b->memory() ? -1 : 1; 00211 case "count": 00212 return $a->count() > $b->count() ? -1 : 1; 00213 case "time_per_call": 00214 return $a->timePerCall() > $b->timePerCall() ? -1 : 1; 00215 case "memory_per_call": 00216 return $a->memoryPerCall() > $b->memoryPerCall() ? -1 : 1; 00217 case "calls_per_req": 00218 return $a->callsPerRequest() > $b->callsPerRequest() ? -1 : 1; 00219 case "time_per_req": 00220 return $a->timePerRequest() > $b->timePerRequest() ? -1 : 1; 00221 case "memory_per_req": 00222 return $a->memoryPerRequest() > $b->memoryPerRequest() ? -1 : 1; 00223 } 00224 } 00225 00226 $sorts = array( 'time', 'memory', 'count', 'calls_per_req', 'name', 00227 'time_per_call', 'memory_per_call', 'time_per_req', 'memory_per_req' ); 00228 $sort = 'time'; 00229 if ( isset( $_REQUEST['sort'] ) && in_array( $_REQUEST['sort'], $sorts ) ) 00230 $sort = $_REQUEST['sort']; 00231 00232 $res = $dbr->select( 'profiling', '*', array(), 'profileinfo.php', array( 'ORDER BY' => 'pf_name ASC' ) ); 00233 00234 if (isset( $_REQUEST['filter'] ) ) 00235 $filter = $_REQUEST['filter']; 00236 else 00237 $filter = ''; 00238 00239 ?> 00240 <form method="get" action="profileinfo.php"> 00241 <p> 00242 <input type="text" name="filter" value="<?php echo htmlspecialchars($filter)?>"/> 00243 <input type="hidden" name="sort" value="<?php echo htmlspecialchars($sort)?>"/> 00244 <input type="hidden" name="expand" value="<?php echo htmlspecialchars(implode(",", array_keys($expand)))?>"/> 00245 <input type="submit" value="Filter" /> 00246 </p> 00247 </form> 00248 00249 <table cellspacing="0" border="1"> 00250 <tr id="top"> 00251 <th><a href="<?php echo getEscapedProfileUrl( false, 'name' ) ?>">Name</a></th> 00252 <th><a href="<?php echo getEscapedProfileUrl( false, 'time' ) ?>">Time (%)</a></th> 00253 <th><a href="<?php echo getEscapedProfileUrl( false, 'memory' ) ?>">Memory (%)</a></th> 00254 <th><a href="<?php echo getEscapedProfileUrl( false, 'count' ) ?>">Count</a></th> 00255 <th><a href="<?php echo getEscapedProfileUrl( false, 'calls_per_req' ) ?>">Calls/req</a></th> 00256 <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_call' ) ?>">ms/call</a></th> 00257 <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_call' ) ?>">kb/call</a></th> 00258 <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_req' ) ?>">ms/req</a></th> 00259 <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_req' ) ?>">kb/req</a></th> 00260 </tr> 00261 <?php 00262 profile_point::$totaltime = 0.0; 00263 profile_point::$totalcount = 0; 00264 profile_point::$totalmemory = 0.0; 00265 00266 function getEscapedProfileUrl( $_filter = false, $_sort = false, $_expand = false ) { 00267 global $filter, $sort, $expand; 00268 00269 if ( $_expand === false ) 00270 $_expand = $expand; 00271 00272 return htmlspecialchars( 00273 '?' . 00274 wfArrayToCGI( array( 00275 'filter' => $_filter ? $_filter : $filter, 00276 'sort' => $_sort ? $_sort : $sort, 00277 'expand' => implode( ',', array_keys( $_expand ) ) 00278 ) ) 00279 ); 00280 } 00281 00282 $points = array(); 00283 $queries = array(); 00284 $sqltotal = 0.0; 00285 00286 $last = false; 00287 foreach( $res as $o ) { 00288 $next = new profile_point( $o->pf_name, $o->pf_count, $o->pf_time, $o->pf_memory ); 00289 if( $next->name() == '-total' ) { 00290 profile_point::$totaltime = $next->time(); 00291 profile_point::$totalcount = $next->count(); 00292 profile_point::$totalmemory = $next->memory(); 00293 } 00294 if ( $last !== false ) { 00295 if ( preg_match( "/^".preg_quote( $last->name(), "/" )."/", $next->name() ) ) { 00296 $last->add_child($next); 00297 continue; 00298 } 00299 } 00300 $last = $next; 00301 if ( preg_match( "/^query: /", $next->name() ) || preg_match( "/^query-m: /", $next->name() ) ) { 00302 $sqltotal += $next->time(); 00303 $queries[] = $next; 00304 } else { 00305 $points[] = $next; 00306 } 00307 } 00308 00309 $s = new profile_point( "SQL Queries", 0, $sqltotal, 0, 0 ); 00310 foreach ( $queries as $q ) 00311 $s->add_child($q); 00312 $points[] = $s; 00313 00314 usort( $points, "compare_point" ); 00315 00316 foreach ( $points as $point ) { 00317 if ( strlen( $filter ) && !strstr( $point->name(), $filter ) ) 00318 continue; 00319 00320 $point->display( $expand ); 00321 } 00322 ?> 00323 </table> 00324 00325 <p>Total time: <tt><?php printf("%5.02f", profile_point::$totaltime) ?></tt></p> 00326 <p>Total memory: <tt><?php printf("%5.02f", profile_point::$totalmemory / 1024 ) ?></tt></p> 00327 </body> 00328 </html>