abstract class BaseParser in XHProf 8
Class BaseReport
Hierarchy
- class \Drupal\xhprof\XHProfLib\Parser\BaseParser implements ParserInterface
Expanded class hierarchy of BaseParser
File
- src/
XHProfLib/ Parser/ BaseParser.php, line 12
Namespace
Drupal\xhprof\XHProfLib\ParserView source
abstract class BaseParser implements ParserInterface {
protected $stats;
protected $pc_stats;
protected $metrics;
protected $diff_mode;
protected $sort_col;
protected $display_calls;
protected $sort;
protected $symbol;
private $overall_totals = [
"ct" => 0,
"wt" => 0,
"ut" => 0,
"st" => 0,
"cpu" => 0,
"mu" => 0,
"pmu" => 0,
"samples" => 0,
];
/**
* @var \Drupal\xhprof\XHProfLib\Symbol\Symbol
*/
protected $mainSymbol;
/**
* @var \Drupal\xhprof\XHProfLib\Run
*/
protected $run;
/**
* @param $run
* @param $sort
* @param $symbol
*/
public function __construct(Run $run, $sort, $symbol) {
$this->sort = $sort;
$this->run = $run;
$this->symbol = $symbol;
$this->diff_mode = FALSE;
$this->mainSymbol = $run
->getMainSymbol();
$this
->initMetrics($run
->getSymbols(), $symbol, $sort);
}
/**
* @param $symbols
* All profiled symbols.
* @param $symbol
* Set this to show the parent-child report.
* @param $sort
* Metric used to sort.
*/
protected function initMetrics($symbols, $symbol, $sort) {
if (!empty($sort)) {
if (array_key_exists($sort, ReportConstants::getSortableColumns())) {
$this->sort_col = $sort;
}
else {
print "Invalid Sort Key {$sort} specified in URL";
}
}
// For C++ profiler runs, walltime attribute isn't present.
// In that case, use "samples" as the default sort column.
$wt = $this->mainSymbol
->getWt();
if (!isset($wt)) {
if ($this->sort_col == "wt") {
$this->sort_col = "samples";
}
// C++ profiler data doesn't have call counts.
// ideally we should check to see if "ct" metric
// is present for "main()". But currently "ct"
// metric is artificially set to 1. So, relying
// on absence of "wt" metric instead.
$this->display_calls = FALSE;
}
else {
$this->display_calls = TRUE;
}
// parent/child report doesn't support exclusive times yet.
// So, change sort hyperlinks to closest fit.
if (!empty($symbol)) {
$this->sort_col = str_replace("excl_", "", $this->sort_col);
}
if ($this->display_calls) {
$this->stats = [
"fn",
"ct",
"Calls%",
];
}
else {
$this->stats = [
"fn",
];
}
$this->pc_stats = $this->stats;
$possible_metrics = $this
->getPossibleMetrics($symbols);
foreach ($possible_metrics as $metric => $desc) {
$mainMetric = $this->mainSymbol
->getMetric($metric);
if (isset($mainMetric)) {
$metrics[] = $metric;
// flat (top-level reports): we can compute
// exclusive metrics reports as well.
$this->stats[] = $metric;
$this->stats[] = "I" . $desc[0] . "%";
$this->stats[] = "excl_" . $metric;
$this->stats[] = "E" . $desc[0] . "%";
// parent/child report for a function: we can
// only breakdown inclusive times correctly.
$this->pc_stats[] = $metric;
$this->pc_stats[] = "I" . $desc[0] . "%";
}
}
}
/**
* @return array
*/
public function getPossibleMetrics() {
return [
"wt" => [
"Wall",
"μs",
"walltime",
],
"ut" => [
"User",
"μs",
"user cpu time",
],
"st" => [
"Sys",
"μs",
"system cpu time",
],
"cpu" => [
"Cpu",
"μs",
"cpu time",
],
"mu" => [
"MUse",
"bytes",
"memory usage",
],
"pmu" => [
"PMUse",
"bytes",
"peak memory usage",
],
"samples" => [
"Samples",
"samples",
"cpu time",
],
];
}
/**
* @return array
*/
public function getMetrics() {
// get list of valid metrics
$possible_metrics = $this
->getPossibleMetrics();
// return those that are present in the raw data.
// We'll just look at the root of the subtree for this.
$metrics = [];
foreach ($possible_metrics as $metric => $desc) {
$mainMetric = $this->mainSymbol
->getMetric($metric);
if (isset($mainMetric)) {
$metrics[] = $metric;
}
}
return $metrics;
}
/**
* @param Symbol[] $symbols
*
* @return array
*/
protected function computeFlatInfo($symbols) {
$metrics = $this
->getMetrics();
// Compute inclusive times for each function.
$symbol_tab = $this
->computeInclusiveTimes($symbols);
// Total metric value is the metric value for "main()".
foreach ($metrics as $metric) {
$this->overall_totals[$metric] = $this->mainSymbol
->getMetric($metric);
}
// Initialize exclusive (self) metric value to inclusive metric value to start with.
// In the same pass, also add up the total number of function calls.
foreach ($symbol_tab as $symbol => $info) {
foreach ($metrics as $metric) {
$symbol_tab[$symbol]["excl_" . $metric] = $symbol_tab[$symbol][$metric];
}
// Keep track of total number of calls.
$this->overall_totals["ct"] += $info["ct"];
}
// Adjust exclusive times by deducting inclusive time of children.
foreach ($symbols as $symbol) {
$parent = $symbol
->getParent();
if ($parent) {
foreach ($metrics as $metric) {
// make sure the parent exists hasn't been pruned.
if (isset($symbol_tab[$parent])) {
$symbol_tab[$parent]["excl_" . $metric] -= $symbol
->getMetric($metric);
}
}
}
}
return $symbol_tab;
}
/**
* @param Symbol[] $symbols
*
* @return array
*/
protected function computeInclusiveTimes($symbols) {
$metrics = $this
->getMetrics();
$symbol_tab = [];
/*
* First compute inclusive time for each function and total
* call count for each function across all parents the
* function is called from.
*/
foreach ($symbols as $symbol) {
$child = $symbol
->getChild();
if (!isset($symbol_tab[$child])) {
$symbol_tab[$child] = [
"ct" => $symbol
->getCt(),
];
foreach ($metrics as $metric) {
$symbol_tab[$child][$metric] = $symbol
->getMetric($metric);
}
}
else {
// increment call count for this child
$symbol_tab[$child]["ct"] += $symbol
->getCt();
// update inclusive times/metric for this child
foreach ($metrics as $metric) {
$symbol_tab[$child][$metric] += $symbol
->getMetric($metric);
}
}
}
return $symbol_tab;
}
/**
* @param Symbol[] $symbols
* @param $functions_to_keep
*
* @return array
*/
function trimRun($symbols, $functions_to_keep) {
// convert list of functions to a hash with function as the key
$function_map = array_fill_keys($functions_to_keep, 1);
// always keep main() as well so that overall totals can still
// be computed if need be.
$function_map['main()'] = 1;
$new_symbols = [];
foreach ($symbols as $symbol) {
$parent = $symbol
->getParent();
$child = $symbol
->getChild();
if (isset($function_map[$parent]) || isset($function_map[$child])) {
$new_symbols["{$parent}==>{$child}"] = $symbol;
}
}
return $new_symbols;
}
/**
* @param $arr
* @param $k
* @param $v
*
* @return mixed
*/
function arraySet($arr, $k, $v) {
$arr[$k] = $v;
return $arr;
}
/**
* @param $arr
* @param $k
*
* @return mixed
*/
function arrayUnset($arr, $k) {
unset($arr[$k]);
return $arr;
}
/**
* @return mixed
*/
public function getTotals() {
return $this->overall_totals;
}
/**
* @return mixed
*/
public function getDisplayCalls() {
return $this->display_calls;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
BaseParser:: |
protected | property | ||
BaseParser:: |
protected | property | ||
BaseParser:: |
protected | property | ||
BaseParser:: |
protected | property | ||
BaseParser:: |
private | property | ||
BaseParser:: |
protected | property | ||
BaseParser:: |
protected | property | ||
BaseParser:: |
protected | property | ||
BaseParser:: |
protected | property | ||
BaseParser:: |
protected | property | ||
BaseParser:: |
protected | property | ||
BaseParser:: |
function | |||
BaseParser:: |
function | |||
BaseParser:: |
protected | function | ||
BaseParser:: |
protected | function | ||
BaseParser:: |
public | function | ||
BaseParser:: |
public | function | ||
BaseParser:: |
public | function | ||
BaseParser:: |
public | function | ||
BaseParser:: |
protected | function | ||
BaseParser:: |
function | |||
BaseParser:: |
public | function | 2 | |
ParserInterface:: |
public | function | 2 |