public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $data = $this->profileData; $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($data, $totals); unset($GLOBALS['display_calls']); $symbol = $this->symbol; $children = array(); $parents = array(); foreach ($this->profileData as $key => $counters) { if (strpos($key, '==>') !== false) { list($parent, $child) = explode('==>', $key, 2); } else { continue; } if ($parent == $symbol) { $children[$key] = $child; } else { if ($child == $symbol) { $parents[$key] = $parent; } } } $rows = array(); $rows[] = array(pht('Metrics for this Call'), '', '', ''); $rows[] = $this->formatRow(array($symbol, $flat[$symbol]['ct'], $flat[$symbol]['wt'], 1.0)); $rows[] = array(pht('Parent Calls'), '', '', ''); foreach ($parents as $key => $name) { $rows[] = $this->formatRow(array($name, $data[$key]['ct'], $data[$key]['wt'], '')); } $rows[] = array(pht('Child Calls'), '', '', ''); $child_rows = array(); foreach ($children as $key => $name) { $child_rows[] = array($name, $data[$key]['ct'], $data[$key]['wt'], $data[$key]['wt'] / $flat[$symbol]['wt']); } $child_rows = isort($child_rows, 2); $child_rows = array_reverse($child_rows); $rows = array_merge($rows, array_map(array($this, 'formatRow'), $child_rows)); $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Symbol'), pht('Count'), pht('Wall Time'), '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n')); $panel = new PHUIObjectBoxView(); $panel->setHeaderText(pht('XHProf Profile')); $panel->appendChild($table); return $panel->render(); }
public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($this->profileData, $totals); unset($GLOBALS['display_calls']); $aggregated = array(); foreach ($flat as $call => $counters) { $parts = explode('@', $call, 2); $agg_call = reset($parts); if (empty($aggregated[$agg_call])) { $aggregated[$agg_call] = $counters; } else { foreach ($aggregated[$agg_call] as $key => $val) { if ($key != 'wt') { $aggregated[$agg_call][$key] += $counters[$key]; } } } } $flat = $aggregated; $flat = isort($flat, 'wt'); $flat = array_reverse($flat); $rows = array(); $rows[] = array(pht('Total'), number_format($totals['ct']), number_format($totals['wt']) . ' us', '100.0%', number_format($totals['wt']) . ' us', '100.0%'); if ($this->limit) { $flat = array_slice($flat, 0, $this->limit); } foreach ($flat as $call => $counters) { $rows[] = array($this->renderSymbolLink($call), number_format($counters['ct']), number_format($counters['wt']) . ' us', sprintf('%.1f%%', 100 * $counters['wt'] / $totals['wt']), number_format($counters['excl_wt']) . ' us', sprintf('%.1f%%', 100 * $counters['excl_wt'] / $totals['wt'])); } Javelin::initBehavior('phabricator-tooltips'); $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Symbol'), pht('Count'), javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Total wall time spent in this function and all of ' . 'its children (children are other functions it called ' . 'while executing).'), 'size' => 200)), pht('Wall Time (Inclusive)')), '%', javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Wall time spent in this function, excluding time ' . 'spent in children (children are other functions it ' . 'called while executing).'), 'size' => 200)), pht('Wall Time (Exclusive)')), '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n', 'n', 'n')); $panel = new PHUIObjectBoxView(); $header = id(new PHUIHeaderView())->setHeader(pht('XHProf Profile')); if ($this->file) { $button = id(new PHUIButtonView())->setHref($this->file->getBestURI())->setText(pht('Download %s Profile', '.xhprof'))->setTag('a'); $header->addActionLink($button); } $panel->setHeader($header); $panel->appendChild($table); return $panel->render(); }