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
13 changes: 4 additions & 9 deletions src/components/flame-graph/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type {
SamplesLikeTable,
InnerWindowID,
Page,
SampleCategoriesAndSubcategories,
} from 'firefox-profiler/types';

import type {
Expand All @@ -55,8 +56,6 @@ export type OwnProps = {
readonly thread: Thread;
readonly weightType: WeightType;
readonly innerWindowIDToPageMap: Map<InnerWindowID, Page> | null;
readonly unfilteredThread: Thread;
readonly ctssSampleIndexOffset: number;
readonly maxStackDepthPlusOne: number;
readonly flameGraphTiming: FlameGraphTiming;
readonly callNodeInfo: CallNodeInfo;
Expand All @@ -74,7 +73,7 @@ export type OwnProps = {
readonly isInverted: boolean;
readonly callTreeSummaryStrategy: CallTreeSummaryStrategy;
readonly ctssSamples: SamplesLikeTable;
readonly unfilteredCtssSamples: SamplesLikeTable;
readonly ctssSampleCategoriesAndSubcategories: SampleCategoriesAndSubcategories;
readonly tracedTiming: CallTreeTimingsNonInverted | null;
readonly displayStackType: boolean;
};
Expand Down Expand Up @@ -355,8 +354,6 @@ class FlameGraphCanvasImpl extends React.PureComponent<Props> {
}: HoveredStackTiming): React.ReactNode => {
const {
thread,
unfilteredThread,
ctssSampleIndexOffset,
flameGraphTiming,
callTree,
callNodeInfo,
Expand All @@ -367,7 +364,7 @@ class FlameGraphCanvasImpl extends React.PureComponent<Props> {
innerWindowIDToPageMap,
weightType,
ctssSamples,
unfilteredCtssSamples,
ctssSampleCategoriesAndSubcategories,
tracedTiming,
displayStackType,
} = this.props;
Expand Down Expand Up @@ -426,11 +423,9 @@ class FlameGraphCanvasImpl extends React.PureComponent<Props> {
? this._getTimingsForCallNodeIndex(
callNodeIndex,
callNodeInfo,
unfilteredThread,
ctssSampleIndexOffset,
categories,
ctssSamples,
unfilteredCtssSamples
ctssSampleCategoriesAndSubcategories
)
: undefined
}
Expand Down
22 changes: 8 additions & 14 deletions src/components/flame-graph/FlameGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import type {
ThreadsKey,
InnerWindowID,
Page,
SampleCategoriesAndSubcategories,
} from 'firefox-profiler/types';

import type { FlameGraphTiming } from 'firefox-profiler/profile-logic/flame-graph';
Expand Down Expand Up @@ -70,8 +71,6 @@ type StateProps = {
readonly thread: Thread;
readonly weightType: WeightType;
readonly innerWindowIDToPageMap: Map<InnerWindowID, Page> | null;
readonly unfilteredThread: Thread;
readonly ctssSampleIndexOffset: number;
readonly maxStackDepthPlusOne: number;
readonly timeRange: StartEndRange;
readonly previewSelection: PreviewSelection | null;
Expand All @@ -87,7 +86,7 @@ type StateProps = {
readonly isInverted: boolean;
readonly callTreeSummaryStrategy: CallTreeSummaryStrategy;
readonly ctssSamples: SamplesLikeTable;
readonly unfilteredCtssSamples: SamplesLikeTable;
readonly ctssSampleCategoriesAndSubcategories: SampleCategoriesAndSubcategories;
readonly tracedTiming: CallTreeTimings | null;
readonly displayStackType: boolean;
};
Expand Down Expand Up @@ -324,8 +323,6 @@ class FlameGraphImpl
override render() {
const {
thread,
unfilteredThread,
ctssSampleIndexOffset,
threadsKey,
maxStackDepthPlusOne,
flameGraphTiming,
Expand All @@ -343,7 +340,7 @@ class FlameGraphImpl
innerWindowIDToPageMap,
weightType,
ctssSamples,
unfilteredCtssSamples,
ctssSampleCategoriesAndSubcategories,
tracedTiming,
displayStackType,
} = this.props;
Expand Down Expand Up @@ -391,8 +388,6 @@ class FlameGraphImpl
thread,
innerWindowIDToPageMap,
weightType,
unfilteredThread,
ctssSampleIndexOffset,
maxStackDepthPlusOne,
flameGraphTiming,
callTree,
Expand All @@ -410,7 +405,7 @@ class FlameGraphImpl
interval,
isInverted,
ctssSamples,
unfilteredCtssSamples,
ctssSampleCategoriesAndSubcategories,
tracedTiming: tracedTimingNonInverted,
displayStackType,
}}
Expand All @@ -437,7 +432,6 @@ export const FlameGraph = explicitConnectWithForwardRef<
>({
mapStateToProps: (state) => ({
thread: selectedThreadSelectors.getFilteredThread(state),
unfilteredThread: selectedThreadSelectors.getThread(state),
weightType: selectedThreadSelectors.getWeightTypeForCallTree(state),
// Use the filtered call node max depth, rather than the preview filtered one, so
// that the viewport height is stable across preview selections.
Expand All @@ -461,10 +455,10 @@ export const FlameGraph = explicitConnectWithForwardRef<
selectedThreadSelectors.getCallTreeSummaryStrategy(state),
innerWindowIDToPageMap: getInnerWindowIDToPageMap(state),
ctssSamples: selectedThreadSelectors.getPreviewFilteredCtssSamples(state),
ctssSampleIndexOffset:
selectedThreadSelectors.getPreviewFilteredCtssSampleIndexOffset(state),
unfilteredCtssSamples:
selectedThreadSelectors.getUnfilteredCtssSamples(state),
ctssSampleCategoriesAndSubcategories:
selectedThreadSelectors.getPreviewFilteredCtssSampleCategoriesAndSubcategories(
state
),
tracedTiming: selectedThreadSelectors.getTracedTiming(state),
displayStackType: getProfileUsesMultipleStackTypes(state),
}),
Expand Down
2 changes: 0 additions & 2 deletions src/components/shared/thread/ActivityGraphCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ export class ActivityGraphCanvas extends React.PureComponent<CanvasProps> {
sampleIndexOffset,
samplesSelectedStates,
treeOrderSampleComparator,
categories,
enableCPUUsage,
width,
height,
Expand All @@ -158,7 +157,6 @@ export class ActivityGraphCanvas extends React.PureComponent<CanvasProps> {
enableCPUUsage,
xPixelsPerMs: canvasPixelWidth / (rangeEnd - rangeStart),
treeOrderSampleComparator,
greyCategoryIndex: categories.findIndex((c) => c.color === 'grey') || 0,
categoryDrawStyles: this._getCategoryDrawStyles(ctx!),
});

Expand Down
22 changes: 4 additions & 18 deletions src/components/shared/thread/ActivityGraphFills.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ type RenderedComponentSettings = {
readonly treeOrderSampleComparator:
| ((a: IndexIntoSamplesTable, b: IndexIntoSamplesTable) => number)
| null;
readonly greyCategoryIndex: IndexIntoCategoryList;
readonly samplesSelectedStates: null | Array<SelectedState>;
readonly categoryDrawStyles: CategoryDrawStyles;
};
Expand Down Expand Up @@ -215,9 +214,8 @@ export class ActivityGraphFillComputer {
_accumulateSampleCategories() {
const {
fullThread,
rangeFilteredThread: { samples, stackTable },
rangeFilteredThread: { samples },
interval,
greyCategoryIndex,
enableCPUUsage,
sampleIndexOffset,
} = this.renderedComponentSettings;
Expand All @@ -242,11 +240,7 @@ export class ActivityGraphFillComputer {
const { threadCPURatio } = samples;
for (let i = 0; i < samples.length - 1; i++) {
const nextSampleTime = samples.time[i + 1];
const stackIndex = samples.stack[i];
const category =
stackIndex === null
? greyCategoryIndex
: stackTable.category[stackIndex];
const category = samples.category[i];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fewer branches!

Copy link
Contributor Author

@mstange mstange Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, fewer branches, but more importantly less memory traffic. Now it reads one byte per sample instead of 16 bytes (8 bytes for the stack + 8 bytes for the category), and it reduces the number of dependent loads.


let beforeSampleCpuRatio = 1;
let afterSampleCpuRatio = 1;
Expand All @@ -272,11 +266,7 @@ export class ActivityGraphFillComputer {

// Handle the last sample, which was not covered by the for loop above.
const lastIdx = samples.length - 1;
const lastSampleStack = samples.stack[lastIdx];
const lastSampleCategory =
lastSampleStack !== null
? stackTable.category[lastSampleStack]
: greyCategoryIndex;
const lastSampleCategory = samples.category[lastIdx];

let beforeSampleCpuRatio = 1;
let afterSampleCpuRatio = 1;
Expand Down Expand Up @@ -322,11 +312,7 @@ export class ActivityGraphFillComputer {
beforeSampleCpuRatio: number,
afterSampleCpuRatio: number
) {
const { rangeEnd, rangeStart } = this.renderedComponentSettings;
if (sampleTime < rangeStart || sampleTime >= rangeEnd) {
return;
}

const { rangeStart } = this.renderedComponentSettings;
const percentageBuffers = this.mutablePercentageBuffers[category];
const percentageBuffer = this._pickPercentageBuffer(
percentageBuffers,
Expand Down
21 changes: 21 additions & 0 deletions src/profile-logic/call-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import type {
CallNodeSelfAndSummary,
SelfAndTotal,
BalancedNativeAllocationsTable,
SampleCategoriesAndSubcategories,
IndexIntoCategoryList,
} from 'firefox-profiler/types';
import { ResourceType } from 'firefox-profiler/types';

Expand Down Expand Up @@ -1225,6 +1227,25 @@ export function extractUnfilteredSamplesLikeTable(
}
}

export function computeUnfilteredCtssSampleCategoriesAndSubcategories(
thread: Thread,
ctssSamples: SamplesLikeTable,
defaultCategory: IndexIntoCategoryList
): SampleCategoriesAndSubcategories {
if (ctssSamples === thread.samples) {
const { category, subcategory } = thread.samples;
return {
sampleCategories: category,
sampleSubcategories: subcategory,
};
}
return ProfileData.computeSampleCategoriesAndSubcategories(
ctssSamples.stack,
thread.stackTable,
defaultCategory
);
}

/**
* This function is extremely similar to computeCallNodeSelfAndSummary,
* but is specialized for converting sample counts into traced timing. Samples
Expand Down
4 changes: 2 additions & 2 deletions src/profile-logic/data-structures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export function getEmptyStackTable(): StackTable {
// be caught by the type system.
frame: [],
prefix: [],
category: [],
subcategory: [],
category: new Uint8Array(),
subcategory: new Uint8Array(),
length: 0,
};
}
Expand Down
Loading