Skip to content

Commit aea780c

Browse files
committed
Add memoized selectors for hasUseful*
1 parent 7eac8d8 commit aea780c

File tree

5 files changed

+50
-30
lines changed

5 files changed

+50
-30
lines changed

src/components/shared/StackSettings.js

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {
2424
import { PanelSearch } from './PanelSearch';
2525

2626
import {
27-
hasUsefulSamples,
2827
toValidImplementationFilter,
2928
toValidCallTreeSummaryStrategy,
3029
} from 'firefox-profiler/profile-logic/profile-data';
@@ -271,28 +270,24 @@ export const StackSettings = explicitConnect<
271270
StateProps,
272271
DispatchProps
273272
>({
274-
mapStateToProps: (state) => {
275-
const thread = selectedThreadSelectors.getThread(state);
276-
const { samples, jsAllocations, nativeAllocations } = thread;
277-
return {
278-
invertCallstack: getInvertCallstack(state),
279-
selectedTab: getSelectedTab(state),
280-
showUserTimings: getShowUserTimings(state),
281-
implementationFilter: getImplementationFilter(state),
282-
currentSearchString: getCurrentSearchString(state),
283-
hasUsefulTimingSamples: hasUsefulSamples(samples, thread),
284-
hasUsefulJsAllocations:
285-
jsAllocations !== undefined && hasUsefulSamples(jsAllocations, thread),
286-
hasUsefulNativeAllocations:
287-
nativeAllocations !== undefined &&
288-
hasUsefulSamples(nativeAllocations, thread),
289-
canShowRetainedMemory:
290-
selectedThreadSelectors.getCanShowRetainedMemory(state),
291-
callTreeSummaryStrategy:
292-
selectedThreadSelectors.getCallTreeSummaryStrategy(state),
293-
allowSwitchingStackType: getProfileUsesMultipleStackTypes(state),
294-
};
295-
},
273+
mapStateToProps: (state) => ({
274+
invertCallstack: getInvertCallstack(state),
275+
selectedTab: getSelectedTab(state),
276+
showUserTimings: getShowUserTimings(state),
277+
implementationFilter: getImplementationFilter(state),
278+
currentSearchString: getCurrentSearchString(state),
279+
hasUsefulTimingSamples:
280+
selectedThreadSelectors.getHasUsefulTimingSamples(state),
281+
hasUsefulJsAllocations:
282+
selectedThreadSelectors.getHasUsefulJsAllocations(state),
283+
hasUsefulNativeAllocations:
284+
selectedThreadSelectors.getHasUsefulNativeAllocations(state),
285+
canShowRetainedMemory:
286+
selectedThreadSelectors.getCanShowRetainedMemory(state),
287+
callTreeSummaryStrategy:
288+
selectedThreadSelectors.getCallTreeSummaryStrategy(state),
289+
allowSwitchingStackType: getProfileUsesMultipleStackTypes(state),
290+
}),
296291
mapDispatchToProps: {
297292
changeImplementationFilter,
298293
changeInvertCallstack,

src/profile-logic/profile-data.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,11 +1280,11 @@ export function filterThreadByTab(
12801280
* A useful sample being one that isn't a "(root)" sample.
12811281
*/
12821282
export function hasUsefulSamples(
1283-
table: SamplesLikeTable,
1283+
table?: SamplesLikeTable,
12841284
thread: Thread
12851285
): boolean {
12861286
const { stackTable, frameTable, funcTable, stringTable } = thread;
1287-
if (table.length === 0 || stackTable.length === 0) {
1287+
if (table === undefined || table.length === 0 || stackTable.length === 0) {
12881288
return false;
12891289
}
12901290
const stackIndex = table.stack.find((stack) => stack !== null);
@@ -1303,7 +1303,7 @@ export function hasUsefulSamples(
13031303
if (stringTable.getString(stringIndex) === '(root)') {
13041304
// If the first sample's stack is only the root, check if any other
13051305
// sample is different.
1306-
return table.stack.some((s) => s !== stackIndex);
1306+
return table.stack.some((s) => s !== null && s !== stackIndex);
13071307
}
13081308
}
13091309
return true;

src/selectors/per-thread/composed.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export function getComposedSelectorsPerThread(
8686

8787
const { samples, jsAllocations, nativeAllocations } = thread;
8888
const hasSamples = [samples, jsAllocations, nativeAllocations].some(
89-
(table) => table && hasUsefulSamples(table, thread)
89+
(table) => hasUsefulSamples(table, thread)
9090
);
9191
if (!hasSamples) {
9292
visibleTabs = visibleTabs.filter(

src/selectors/per-thread/thread.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import type {
2828
JsTracerTable,
2929
SamplesTable,
3030
NativeAllocationsTable,
31+
JsAllocationsTable,
3132
SamplesLikeTable,
3233
Selector,
3334
ThreadViewOptions,
@@ -88,6 +89,8 @@ export function getThreadSelectorsPerThread(
8889
const getNativeAllocations: Selector<NativeAllocationsTable | void> = (
8990
state
9091
) => getThread(state).nativeAllocations;
92+
const getJsAllocations: Selector<JsAllocationsTable | void> = (state) =>
93+
getThread(state).jsAllocations;
9194
const getThreadRange: Selector<StartEndRange> = (state) =>
9295
// This function is already memoized in profile-data.js, so we don't need to
9396
// memoize it here with `createSelector`.
@@ -385,6 +388,24 @@ export function getThreadSelectorsPerThread(
385388
ProfileSelectors.getProfileViewOptions(state).perThread[threadsKey] ||
386389
defaultThreadViewOptions;
387390

391+
const getHasUsefulTimingSamples: Selector<boolean> = createSelector(
392+
getSamplesTable,
393+
getThread,
394+
ProfileData.hasUsefulSamples
395+
);
396+
397+
const getHasUsefulJsAllocations: Selector<boolean> = createSelector(
398+
getJsAllocations,
399+
getThread,
400+
ProfileData.hasUsefulSamples
401+
);
402+
403+
const getHasUsefulNativeAllocations: Selector<boolean> = createSelector(
404+
getNativeAllocations,
405+
getThread,
406+
ProfileData.hasUsefulSamples
407+
);
408+
388409
/**
389410
* We can only compute the retained memory in the versions of the native allocations
390411
* format that provide the memory address. The earlier versions did not have
@@ -455,6 +476,7 @@ export function getThreadSelectorsPerThread(
455476
getSamplesTable,
456477
getSamplesWeightType,
457478
getNativeAllocations,
479+
getJsAllocations,
458480
getThreadRange,
459481
getFilteredThread,
460482
getRangeFilteredThread,
@@ -474,6 +496,9 @@ export function getThreadSelectorsPerThread(
474496
getJsTracerTable,
475497
getExpensiveJsTracerTiming,
476498
getExpensiveJsTracerLeafTiming,
499+
getHasUsefulTimingSamples,
500+
getHasUsefulJsAllocations,
501+
getHasUsefulNativeAllocations,
477502
getCanShowRetainedMemory,
478503
getCPUProcessedThread,
479504
getTabFilteredThread,

src/test/store/useful-tabs.test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ describe('getUsefulTabs', function () {
103103

104104
it('shows sample related tabs even when there are only allocation samples in the profile', function () {
105105
const { profile } = getProfileWithUnbalancedNativeAllocations();
106-
profile.threads.forEach(
107-
(thread) => (thread.samples = getEmptySamplesTableWithEventDelay())
108-
);
106+
for (const thread of profile.threads) {
107+
thread.samples = getEmptySamplesTableWithEventDelay();
108+
}
109109
const { getState } = storeWithProfile(profile);
110110
expect(selectedThreadSelectors.getUsefulTabs(getState())).toEqual([
111111
'calltree',

0 commit comments

Comments
 (0)