7use Wikimedia\RunningStat;
49 public function __construct( array $data, array $config = [] ) {
55 $this->hieraData = $this->
pruneData( $data );
85 return $this->hieraData;
99 return array_pad( explode(
'==>', $key, 2 ), -2,
null );
110 if ( !$this->config[
'include'] ) {
114 $want = array_fill_keys( $this->config[
'include'],
true );
115 $want[
'main()'] =
true;
118 foreach ( $data as $key => $stats ) {
119 [ $parent, $child ] = self::splitKey( $key );
120 if ( ( $parent !==
null && isset( $want[$parent] ) ) || isset( $want[$child] ) ) {
121 $keep[$key] = $stats;
146 if ( $this->inclusive ===
null ) {
147 $main = $this->hieraData[
'main()'];
148 $hasCpu = isset( $main[
'cpu'] );
149 $hasMu = isset( $main[
'mu'] );
150 $hasAlloc = isset( $main[
'alloc'] );
153 foreach ( $this->hieraData as $key => $stats ) {
154 [ , $child ] = self::splitKey( $key );
158 'wt' =>
new RunningStat(),
161 $inclusive[$child][
'cpu'] =
new RunningStat();
165 $inclusive[$child][
'pmu'] =
new RunningStat();
168 $inclusive[$child][
'alloc'] =
new RunningStat();
169 $inclusive[$child][
'free'] =
new RunningStat();
174 foreach ( $stats as $stat => $value ) {
175 if ( $stat ===
'ct' ) {
184 for ( $i = 0; $i < $stats[
'ct']; $i++ ) {
186 $value / $stats[
'ct']
195 foreach ( $stats as $name => $value ) {
196 if ( $value instanceof RunningStat ) {
197 $total = $value->getMean() * $value->getCount();
198 $percent = ( isset( $main[$name] ) && $main[$name] )
199 ? 100 * $total / $main[$name]
203 'min' => $value->min,
204 'mean' => $value->getMean(),
205 'max' => $value->max,
206 'variance' => $value->m2,
207 'percent' => $percent,
214 $this->config[
'sort'],
'total'
218 return $this->inclusive;
233 if ( $this->complete ===
null ) {
237 foreach ( $this->complete as $func => $stats ) {
238 foreach ( $stats as $stat => $value ) {
239 if ( $stat ===
'ct' ) {
243 $this->complete[$func][$stat][
'exclusive'] = $value[
'total'];
246 $this->complete[$func][
'calls'] = [];
247 $this->complete[$func][
'subcalls'] = [];
250 foreach ( $this->hieraData as $key => $stats ) {
251 [ $parent, $child ] = self::splitKey( $key );
252 if ( $parent !==
null ) {
254 $this->complete[$child][
'calls'][$parent] = $stats;
255 $this->complete[$parent][
'subcalls'][$child] = $stats;
258 if ( $parent !==
null && isset( $this->complete[$parent] ) ) {
260 foreach ( $stats as $stat => $value ) {
261 if ( $stat ===
'ct' ) {
265 if ( !isset( $this->complete[$parent][$stat] ) ) {
270 $this->complete[$parent][$stat][
'exclusive'] -= $value;
275 uasort( $this->complete, self::makeSortFunction(
276 $this->config[
'sort'],
'exclusive'
279 return $this->complete;
291 if ( isset( $edges[$function][
'calls'] ) ) {
292 return array_keys( $edges[$function][
'calls'] );
307 if ( isset( $edges[$function][
'subcalls'] ) ) {
308 return array_keys( $edges[$function][
'subcalls'] );
323 $func => $this->hieraData[$func],
329 foreach ( $callees as $callee ) {
330 $call =
"{$func}==>{$callee}";
331 if ( $maxCall ===
null ||
332 $this->hieraData[$call][$metric] >
333 $this->hieraData[$maxCall][$metric]
335 $maxCallee = $callee;
339 if ( $maxCall !==
null ) {
340 $path[$maxCall] = $this->hieraData[$maxCall];
356 return static function ( $a, $b ) use ( $key, $sub ) {
357 if ( isset( $a[$key] ) && isset( $b[$key] ) ) {
360 $valA = is_array( $a[$key] ) ? $a[$key][$sub] : $a[$key];
361 $valB = is_array( $b[$key] ) ? $b[$key][$sub] : $b[$key];
362 return $valB <=> $valA;
365 return isset( $a[$key] ) ? -1 : 1;
Convenience class for working with XHProf profiling data https://github.com/phacility/xhprof.
getCriticalPath( $metric='wt')
Find the critical path for the given metric.
array[] $complete
Per-function inclusive and exclusive data.
pruneData( $data)
Remove data for functions that are not included in the 'include' configuration array.
getInclusiveMetrics()
Get the inclusive metrics for each function call.
array[][] $inclusive
Per-function inclusive data.
static makeSortFunction( $key, $sub)
Make a closure to use as a sort function.
getCallees( $function)
Get a list of all callees from a given function.
getRawData()
Get raw data collected by xhprof.
__construct(array $data, array $config=[])
Configuration data can contain:
array[] $hieraData
Hierarchical profiling data returned by xhprof.
getCallers( $function)
Get a list of all callers of a given function.
static splitKey( $key)
Convert an xhprof data key into an array of ['parent', 'child'] function names.
getCompleteMetrics()
Get the inclusive and exclusive metrics for each function call.