mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 18:24:02 +00:00
Bug 1074899 - Add self time and self percentage to the profiler. r=vporof
This commit is contained in:
parent
cd2741e613
commit
318b30af30
@ -107,11 +107,19 @@
|
||||
<label class="plain call-tree-header"
|
||||
type="duration"
|
||||
crop="end"
|
||||
value="&profilerUI.table.duration;"/>
|
||||
value="&profilerUI.table.totalDuration;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="self-duration"
|
||||
crop="end"
|
||||
value="&profilerUI.table.selfDuration;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="percentage"
|
||||
crop="end"
|
||||
value="&profilerUI.table.percentage;"/>
|
||||
value="&profilerUI.table.totalPercentage;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="self-percentage"
|
||||
crop="end"
|
||||
value="&profilerUI.table.selfPercentage;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="samples"
|
||||
crop="end"
|
||||
|
@ -22,9 +22,9 @@ function test() {
|
||||
is(container.childNodes[0].className, "call-tree-item",
|
||||
"The root node in the tree has the correct class name.");
|
||||
|
||||
is(container.childNodes[0].childNodes.length, 4,
|
||||
is(container.childNodes[0].childNodes.length, 6,
|
||||
"The root node in the tree has the correct number of children.");
|
||||
is(container.childNodes[0].querySelectorAll(".call-tree-cell").length, 4,
|
||||
is(container.childNodes[0].querySelectorAll(".call-tree-cell").length, 6,
|
||||
"The root node in the tree has only 'call-tree-cell' children.");
|
||||
|
||||
is(container.childNodes[0].childNodes[0].getAttribute("type"), "duration",
|
||||
@ -32,19 +32,29 @@ function test() {
|
||||
is(container.childNodes[0].childNodes[0].getAttribute("value"), "18",
|
||||
"The root node in the tree has the correct duration cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[1].getAttribute("type"), "percentage",
|
||||
is(container.childNodes[0].childNodes[1].getAttribute("type"), "self-duration",
|
||||
"The root node in the tree has a self-duration cell.");
|
||||
is(container.childNodes[0].childNodes[1].getAttribute("value"), "0",
|
||||
"The root node in the tree has the correct self-duration cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[2].getAttribute("type"), "percentage",
|
||||
"The root node in the tree has a percentage cell.");
|
||||
is(container.childNodes[0].childNodes[1].getAttribute("value"), "100%",
|
||||
is(container.childNodes[0].childNodes[2].getAttribute("value"), "100%",
|
||||
"The root node in the tree has the correct percentage cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[2].getAttribute("type"), "samples",
|
||||
is(container.childNodes[0].childNodes[3].getAttribute("type"), "self-percentage",
|
||||
"The root node in the tree has a self-percentage cell.");
|
||||
is(container.childNodes[0].childNodes[3].getAttribute("value"), "0%",
|
||||
"The root node in the tree has the correct self-percentage cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[4].getAttribute("type"), "samples",
|
||||
"The root node in the tree has an samples cell.");
|
||||
is(container.childNodes[0].childNodes[2].getAttribute("value"), "3",
|
||||
is(container.childNodes[0].childNodes[4].getAttribute("value"), "3",
|
||||
"The root node in the tree has the correct samples cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[3].getAttribute("type"), "function",
|
||||
is(container.childNodes[0].childNodes[5].getAttribute("type"), "function",
|
||||
"The root node in the tree has a function cell.");
|
||||
is(container.childNodes[0].childNodes[3].style.MozMarginStart, "0px",
|
||||
is(container.childNodes[0].childNodes[5].style.MozMarginStart, "0px",
|
||||
"The root node in the tree has the correct indentation.");
|
||||
|
||||
finish();
|
||||
|
@ -42,18 +42,22 @@ function test() {
|
||||
ok(!A.target.querySelector(".call-tree-category").hidden,
|
||||
"The .A.B.C node's category label cell should not be hidden.");
|
||||
|
||||
is(C.target.childNodes.length, 4,
|
||||
is(C.target.childNodes.length, 6,
|
||||
"The number of columns displayed for tree items is correct.");
|
||||
is(C.target.childNodes[0].getAttribute("type"), "duration",
|
||||
"The first column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[1].getAttribute("type"), "percentage",
|
||||
is(C.target.childNodes[1].getAttribute("type"), "self-duration",
|
||||
"The second column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[2].getAttribute("type"), "samples",
|
||||
is(C.target.childNodes[2].getAttribute("type"), "percentage",
|
||||
"The third column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[3].getAttribute("type"), "function",
|
||||
is(C.target.childNodes[3].getAttribute("type"), "self-percentage",
|
||||
"The fourth column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[4].getAttribute("type"), "samples",
|
||||
"The fifth column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[5].getAttribute("type"), "function",
|
||||
"The sixth column displayed for tree items is correct.");
|
||||
|
||||
let functionCell = C.target.childNodes[3];
|
||||
let functionCell = C.target.childNodes[5];
|
||||
|
||||
is(functionCell.childNodes.length, 8,
|
||||
"The number of columns displayed for function cells is correct.");
|
||||
|
@ -18,6 +18,9 @@ const ZOOM_BUTTON_TOOLTIP = L10N.getStr("table.zoom.tooltiptext");
|
||||
const CALL_TREE_INDENTATION = 16; // px
|
||||
const CALL_TREE_AUTO_EXPAND = 3; // depth
|
||||
|
||||
const clamp = (val, min, max) => Math.max(min, Math.min(max, val));
|
||||
const sum = vals => vals.reduce((a, b) => a + b, 0);
|
||||
|
||||
exports.CallView = CallView;
|
||||
|
||||
/**
|
||||
@ -63,10 +66,17 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
this.document = document;
|
||||
|
||||
let frameInfo = this.frame.getInfo();
|
||||
let framePercentage = this.frame.samples / this.root.frame.samples * 100;
|
||||
let framePercentage = this._getPercentage(this.frame.samples);
|
||||
let childrenPercentage = sum([this._getPercentage(c.samples)
|
||||
for (c of this._getChildCalls())]);
|
||||
let selfPercentage = clamp(framePercentage - childrenPercentage, 0, 100);
|
||||
let selfDuration = this.frame.duration - sum([c.duration
|
||||
for (c of this._getChildCalls())]);
|
||||
|
||||
let durationCell = this._createTimeCell(this.frame.duration);
|
||||
let selfDurationCell = this._createTimeCell(selfDuration, true);
|
||||
let percentageCell = this._createExecutionCell(framePercentage);
|
||||
let selfPercentageCell = this._createExecutionCell(selfPercentage, true);
|
||||
let samplesCell = this._createSamplesCell(this.frame.samples);
|
||||
let functionCell = this._createFunctionCell(arrowNode, frameInfo, this.level);
|
||||
|
||||
@ -83,13 +93,29 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
}
|
||||
|
||||
targetNode.appendChild(durationCell);
|
||||
targetNode.appendChild(selfDurationCell);
|
||||
targetNode.appendChild(percentageCell);
|
||||
targetNode.appendChild(selfPercentageCell);
|
||||
targetNode.appendChild(samplesCell);
|
||||
targetNode.appendChild(functionCell);
|
||||
|
||||
return targetNode;
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculate what percentage of all samples the given number of samples is.
|
||||
*/
|
||||
_getPercentage: function (samples) {
|
||||
return samples / this.root.frame.samples * 100;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return an array of this frame's child calls.
|
||||
*/
|
||||
_getChildCalls: function () {
|
||||
return Object.keys(this.frame.calls).map(k => this.frame.calls[k]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Populates this node in the call tree with the corresponding "callees".
|
||||
* These are defined in the `frame` data source for this call view.
|
||||
@ -98,7 +124,7 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
_populateSelf: function(children) {
|
||||
let newLevel = this.level + 1;
|
||||
|
||||
for (let [, newFrame] of _Iterator(this.frame.calls)) {
|
||||
for (let newFrame of this._getChildCalls()) {
|
||||
children.push(new CallView({
|
||||
caller: this,
|
||||
frame: newFrame,
|
||||
@ -114,18 +140,18 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
* Functions creating each cell in this call view.
|
||||
* Invoked by `_displaySelf`.
|
||||
*/
|
||||
_createTimeCell: function(duration) {
|
||||
_createTimeCell: function(duration, isSelf = false) {
|
||||
let cell = this.document.createElement("label");
|
||||
cell.className = "plain call-tree-cell";
|
||||
cell.setAttribute("type", "duration");
|
||||
cell.setAttribute("type", isSelf ? "self-duration" : "duration");
|
||||
cell.setAttribute("crop", "end");
|
||||
cell.setAttribute("value", L10N.numberWithDecimals(duration, 2));
|
||||
return cell;
|
||||
},
|
||||
_createExecutionCell: function(percentage) {
|
||||
_createExecutionCell: function(percentage, isSelf = false) {
|
||||
let cell = this.document.createElement("label");
|
||||
cell.className = "plain call-tree-cell";
|
||||
cell.setAttribute("type", "percentage");
|
||||
cell.setAttribute("type", isSelf ? "self-percentage" : "percentage");
|
||||
cell.setAttribute("crop", "end");
|
||||
cell.setAttribute("value", L10N.numberWithDecimals(percentage, 2) + "%");
|
||||
return cell;
|
||||
|
@ -39,10 +39,12 @@
|
||||
|
||||
<!-- LOCALIZATION NOTE (profilerUI.table.*): These strings are displayed
|
||||
- in the call tree headers for a recording. -->
|
||||
<!ENTITY profilerUI.table.duration "Time (ms)">
|
||||
<!ENTITY profilerUI.table.percentage "Cost">
|
||||
<!ENTITY profilerUI.table.samples "Samples">
|
||||
<!ENTITY profilerUI.table.function "Function">
|
||||
<!ENTITY profilerUI.table.totalDuration "Total Time (ms)">
|
||||
<!ENTITY profilerUI.table.selfDuration "Self Time (ms)">
|
||||
<!ENTITY profilerUI.table.totalPercentage "Total Cost">
|
||||
<!ENTITY profilerUI.table.selfPercentage "Self Cost">
|
||||
<!ENTITY profilerUI.table.samples "Samples">
|
||||
<!ENTITY profilerUI.table.function "Function">
|
||||
|
||||
<!-- LOCALIZATION NOTE (profilerUI.newtab.tooltiptext): The tooltiptext shown
|
||||
- on the "+" (new tab) button for a profile when a selection is available. -->
|
||||
|
@ -251,13 +251,17 @@
|
||||
}
|
||||
|
||||
.call-tree-header[type="duration"],
|
||||
.call-tree-cell[type="duration"] {
|
||||
width: 7em;
|
||||
.call-tree-cell[type="duration"],
|
||||
.call-tree-header[type="self-duration"],
|
||||
.call-tree-cell[type="self-duration"] {
|
||||
width: 9em;
|
||||
}
|
||||
|
||||
.call-tree-header[type="percentage"],
|
||||
.call-tree-cell[type="percentage"] {
|
||||
width: 5em;
|
||||
.call-tree-cell[type="percentage"],
|
||||
.call-tree-header[type="self-percentage"],
|
||||
.call-tree-cell[type="self-percentage"] {
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
.call-tree-header[type="samples"],
|
||||
|
Loading…
x
Reference in New Issue
Block a user