Skip to content
Open
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,
};
}
41 changes: 38 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 getRatioOfRootTotalSummary: 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,16 @@ class FlameGraphTimingNonInverted implements FlameGraphTiming {
return rows;
}

// 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 {
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 +169,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 +462,14 @@ class FlameGraphTimingInverted implements FlameGraphTiming {
return rows;
}

// For a given node / "box", get the sample percentage (as a fraction of 1) that
// should be displayed in the tooltip for this node. 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
6 changes: 6 additions & 0 deletions src/types/profile-derived.ts
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,12 @@ 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, but for the upper wing it is set to the
// total of samples that contain the selected function, so that the root node
// fills the full flame graph width while percentages remain relative to all
// filtered samples.
flameGraphWidthTotal: number;
};

/**
Expand Down
Loading