112 if ( !$this->config[
'include'] ) {
116 $want = array_fill_keys( $this->config[
'include'],
true );
117 $want[
'main()'] =
true;
120 foreach ( $data as $key => $stats ) {
121 [ $parent, $child ] = self::splitKey( $key );
122 if ( ( $parent !==
null && isset( $want[$parent] ) ) || isset( $want[$child] ) ) {
123 $keep[$key] = $stats;
148 if ( $this->inclusive ===
null ) {
149 $main = $this->hieraData[
'main()'];
150 $hasCpu = isset( $main[
'cpu'] );
151 $hasMu = isset( $main[
'mu'] );
152 $hasAlloc = isset( $main[
'alloc'] );
155 foreach ( $this->hieraData as $key => $stats ) {
156 [ , $child ] = self::splitKey( $key );
157 if ( !isset( $inclusive[$child] ) ) {
158 $inclusive[$child] = [
160 'wt' =>
new RunningStat(),
163 $inclusive[$child][
'cpu'] =
new RunningStat();
166 $inclusive[$child][
'mu'] =
new RunningStat();
167 $inclusive[$child][
'pmu'] =
new RunningStat();
170 $inclusive[$child][
'alloc'] =
new RunningStat();
171 $inclusive[$child][
'free'] =
new RunningStat();
175 $inclusive[$child][
'ct'] += $stats[
'ct'];
176 foreach ( $stats as $stat => $value ) {
177 if ( $stat ===
'ct' ) {
181 if ( !isset( $inclusive[$child][$stat] ) ) {
186 for ( $i = 0; $i < $stats[
'ct']; $i++ ) {
187 $inclusive[$child][$stat]->addObservation(
188 $value / $stats[
'ct']
196 foreach ( $inclusive as $func => $stats ) {
197 foreach ( $stats as $name => $value ) {
198 if ( $value instanceof RunningStat ) {
199 $total = $value->getMean() * $value->getCount();
200 $percent = ( isset( $main[$name] ) && $main[$name] )
201 ? 100 * $total / $main[$name]
203 $inclusive[$func][$name] = [
205 'min' => $value->min,
206 'mean' => $value->getMean(),
207 'max' => $value->max,
208 'variance' => $value->m2,
209 'percent' => $percent,
215 uasort( $inclusive, self::makeSortFunction(
216 $this->config[
'sort'],
'total'
218 $this->inclusive = $inclusive;
220 return $this->inclusive;
235 if ( $this->complete ===
null ) {
237 $this->complete = $this->getInclusiveMetrics();
239 foreach ( $this->complete as $func => $stats ) {
240 foreach ( $stats as $stat => $value ) {
241 if ( $stat ===
'ct' ) {
245 $this->complete[$func][$stat][
'exclusive'] = $value[
'total'];
248 $this->complete[$func][
'calls'] = [];
249 $this->complete[$func][
'subcalls'] = [];
252 foreach ( $this->hieraData as $key => $stats ) {
253 [ $parent, $child ] = self::splitKey( $key );
254 if ( $parent !==
null ) {
256 $this->complete[$child][
'calls'][$parent] = $stats;
257 $this->complete[$parent][
'subcalls'][$child] = $stats;
260 if ( $parent !==
null && isset( $this->complete[$parent] ) ) {
262 foreach ( $stats as $stat => $value ) {
263 if ( $stat ===
'ct' ) {
267 if ( !isset( $this->complete[$parent][$stat] ) ) {
272 $this->complete[$parent][$stat][
'exclusive'] -= $value;
277 uasort( $this->complete, self::makeSortFunction(
278 $this->config[
'sort'],
'exclusive'
281 return $this->complete;
325 $func => $this->hieraData[$func],
328 $callees = $this->getCallees( $func );
331 foreach ( $callees as $callee ) {
332 $call =
"{$func}==>{$callee}";
333 if ( $maxCall ===
null ||
334 $this->hieraData[$call][$metric] >
335 $this->hieraData[$maxCall][$metric]
337 $maxCallee = $callee;
341 if ( $maxCall !==
null ) {
342 $path[$maxCall] = $this->hieraData[$maxCall];
358 return static function ( $a, $b ) use ( $key, $sub ) {
359 if ( isset( $a[$key] ) && isset( $b[$key] ) ) {
362 $valA = is_array( $a[$key] ) ? $a[$key][$sub] : $a[$key];
363 $valB = is_array( $b[$key] ) ? $b[$key][$sub] : $b[$key];
364 return $valB <=> $valA;
367 return isset( $a[$key] ) ? -1 : 1;