Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/components/flame-graph/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -419,10 +419,10 @@ class FlameGraphCanvasImpl extends React.PureComponent<Props> {
return null;
}

const ratio =
stackTiming.end[flameGraphTimingIndex] -
stackTiming.start[flameGraphTimingIndex];

const ratio = flameGraphTiming.getRatioOfRootTotalSummary(
depth,
flameGraphTimingIndex
);
let percentage = formatPercent(ratio);
if (tracedTiming) {
const { total } = getSelfAndTotalForCallNode(
Expand Down
17 changes: 14 additions & 3 deletions src/profile-logic/call-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export type CallTreeTimingsNonInverted = {
self: Float64Array;
total: Float64Array;
rootTotalSummary: number; // sum of absolute values, this is used for computing percentages
flameGraphWidthTotal: number; // used as 100% reference for flame graph box widths
};

type TotalAndHasChildren = { total: number; hasChildren: boolean };
Expand Down Expand Up @@ -723,7 +724,11 @@ export function computeCallNodeSelfAndSummary(
rootTotalSummary += abs(callNodeSelf[callNodeIndex]);
}

return { callNodeSelf, rootTotalSummary };
return {
callNodeSelf,
rootTotalSummary,
flameGraphWidthTotal: rootTotalSummary,
};
}

export function getSelfAndTotalForCallNode(
Expand Down Expand Up @@ -894,7 +899,8 @@ export function computeCallTreeTimingsNonInverted(
callNodeSelfAndSummary: CallNodeSelfAndSummary
): CallTreeTimingsNonInverted {
const callNodeTable = callNodeInfo.getCallNodeTable();
const { callNodeSelf, rootTotalSummary } = callNodeSelfAndSummary;
const { callNodeSelf, rootTotalSummary, flameGraphWidthTotal } =
callNodeSelfAndSummary;

// Compute the following variables:
const callNodeTotal = new Float64Array(callNodeTable.length);
Expand Down Expand Up @@ -932,6 +938,7 @@ export function computeCallTreeTimingsNonInverted(
total: callNodeTotal,
callNodeHasChildren,
rootTotalSummary,
flameGraphWidthTotal,
};
}

Expand Down Expand Up @@ -1334,5 +1341,9 @@ export function computeCallNodeTracedSelfAndSummary(
}
}

return { callNodeSelf, rootTotalSummary };
return {
callNodeSelf,
rootTotalSummary,
flameGraphWidthTotal: rootTotalSummary,
};
}
37 changes: 34 additions & 3 deletions src/profile-logic/flame-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,25 @@ export interface FlameGraphTiming {
readonly rowCount: number;
getRow(depth: number): FlameGraphTimingRow;
getAllRowsForTesting(): FlameGraphTimingRow[];

// For a given node / "box", get the sample percentage (as a fraction of 1)
// that should be displayed in the tooltip for this node.
getRatioOfRootTotalSummary(depth: number, indexInRow: number): number;
}

// Returns the width of a box as a fraction of the full flame graph width.
function _getBoxWidth(
flameGraphTiming: FlameGraphTiming,
depth: number,
indexInRow: number
): number {
const row = flameGraphTiming.getRow(depth);
if (indexInRow < 0 || indexInRow >= row.length) {
throw new Error(
`Out-of-bounds call to _getBoxWidth: For depth ${depth}, ${indexInRow} is outside 0..${row.length}`
);
}
return row.end[indexInRow] - row.start[indexInRow];
}

class FlameGraphTimingNonInverted implements FlameGraphTiming {
Expand Down Expand Up @@ -104,8 +123,14 @@ class FlameGraphTimingNonInverted implements FlameGraphTiming {
return rows;
}

getRatioOfRootTotalSummary(depth: number, indexInRow: number): number {
const ratioOfFullWidth = _getBoxWidth(this, depth, indexInRow);
const total = ratioOfFullWidth * this._callTreeTimings.flameGraphWidthTotal;
return total / this._callTreeTimings.rootTotalSummary;
}

_buildNextTimingRow(): void {
const { total, self, rootTotalSummary } = this._callTreeTimings;
const { total, self, flameGraphWidthTotal } = this._callTreeTimings;
const { prefix } = this._callNodeTable;

const depth = this._timingRows.length;
Expand Down Expand Up @@ -142,8 +167,8 @@ class FlameGraphTimingNonInverted implements FlameGraphTiming {
}
startPerCallNode[nodeIndex] = currentStart;

const totalRelative = abs(totalVal / rootTotalSummary);
const selfRelativeVal = abs(self[nodeIndex] / rootTotalSummary);
const totalRelative = abs(totalVal / flameGraphWidthTotal);
const selfRelativeVal = abs(self[nodeIndex] / flameGraphWidthTotal);

const currentEnd = currentStart + totalRelative;
start.push(currentStart);
Expand Down Expand Up @@ -435,6 +460,12 @@ class FlameGraphTimingInverted implements FlameGraphTiming {
return rows;
}

// In the inverted flame graph, box widths are computed relative to
// rootTotalSummary, so the box width is already the ratio we want.
getRatioOfRootTotalSummary(depth: number, indexInRow: number): number {
return _getBoxWidth(this, depth, indexInRow);
}

_compareCallNodesByFuncName = (
a: IndexIntoCallNodeTable,
b: IndexIntoCallNodeTable
Expand Down
1 change: 1 addition & 0 deletions src/test/store/__snapshots__/profile-view.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2362,6 +2362,7 @@ CallTree {
0,
0,
],
"flameGraphWidthTotal": 2,
"rootTotalSummary": 2,
"self": Float64Array [
0,
Expand Down
1 change: 1 addition & 0 deletions src/test/unit/profile-tree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ describe('unfiltered call tree', function () {
type: 'NON_INVERTED',
timings: {
rootTotalSummary: 3,
flameGraphWidthTotal: 3,
callNodeHasChildren: new Uint8Array([1, 1, 1, 1, 0, 1, 0, 1, 0]),
self: new Float64Array([0, 0, 0, 0, 1, 0, 1, 0, 1]),
total: new Float64Array([3, 3, 2, 1, 1, 1, 1, 1, 1]),
Expand Down
3 changes: 3 additions & 0 deletions src/types/profile-derived.ts
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,9 @@ export type CallNodeSelfAndSummary = {
// The sum of absolute values in callNodeSelf.
// This is used for computing the percentages displayed in the call tree.
rootTotalSummary: number;
// The total used as the 100% reference for flame graph box widths.
// Usually equals rootTotalSummary.
flameGraphWidthTotal: number;
};

/**
Expand Down
Loading