Skip to content

Make profile-conversion snapshots more compact and meaningful - #6152

Merged
mstange merged 2 commits into
firefox-devtools:mainfrom
mstange:push-lzsvmxpoywyu
Jul 10, 2026
Merged

Make profile-conversion snapshots more compact and meaningful#6152
mstange merged 2 commits into
firefox-devtools:mainfrom
mstange:push-lzsvmxpoywyu

Conversation

@mstange

@mstange mstange commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Main | Deploy preview

profile-conversion.test.ts was creating a snapshot file that was just a bunch of raw profile JSONs, with around 900 000 lines total.

There's no way to catch regressions with such a test. Whenever we change the shape of the tables in the profile format, it affects so many lines that github's diff viewer will not render the diff, and you wouldn't be able to meaningfully read it anyway.

For example, when I introduced the shared tables, I regressed the dhat importer (it was overwriting some tables with empty tables), and I missed the regression even though the test in theory "caught" it.

This commit replaces the raw profile snapshots with profile "summary" snapshots. See the new snapshot file for examples. I think the new snapshots are definitely more readable / reviewable, but there's also quite a bit of new code to generate them. I'd be happy to cut back on the amount of detail we collect when we make these summaries, to simplify that new code.
(Or maybe we can find a way to share some code with profiler-cli? Not sure.)

The new snapshot file is around 500 lines, and around 160 times smaller than the old snapshot file.

As a second measure of defense, this commit also adds a generic profile consistency checker function called assertProfileIntegrity. This would have caught the dhat regression by itself, because nativeAllocations.stack[0] = 55 would have tripped over the stack table being empty.

@mstange
mstange requested a review from canova July 7, 2026 19:43
@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.80645% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.53%. Comparing base (625c2f6) to head (b33aa23).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
src/test/fixtures/profile-summary.ts 85.80% 22 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6152      +/-   ##
==========================================
+ Coverage   83.50%   83.53%   +0.02%     
==========================================
  Files         342      343       +1     
  Lines       36522    36776     +254     
  Branches    10125    10321     +196     
==========================================
+ Hits        30497    30720     +223     
- Misses       5597     5629      +32     
+ Partials      428      427       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mstange
mstange force-pushed the push-lzsvmxpoywyu branch 2 times, most recently from a0cb4dc to fd7d04a Compare July 7, 2026 19:59

@canova canova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! I like the new assertProfileIntegrity! Also being able to see the full stacks etc. will make it easier to catch stuff.

Comment on lines +168 to +204
type ThreadSummary = {
name: string;
pid: string | number;
tid: string | number;
isMainThread: boolean;
sampleCount: number;
sampleWeightTotal: number | null;
markerCount: number;
markerNamesTop: string[];
jsAllocationCount: number;
nativeAllocationCount: number;
nativeAllocationWeightTotal: number | null;
weightType: string;
};

export type ProfileSummary = {
meta: {
product: string;
importedFrom: string | undefined;
interval: number;
version: number;
preprocessedProfileVersion: number;
symbolicated: boolean | undefined;
categoryNames: string[];
markerSchemaNames: string[];
};
sharedCounts: {
funcs: number;
frames: number;
stacks: number;
resources: number;
nativeSymbols: number;
strings: number;
libs: number;
};
threads: ThreadSummary[];
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah yeah, they kinda look like the summaries that we have in the profiler-cli. But I think it makes sense to keep them split. For example, I don't think sharedCounts makes sense for the cli.

"nativeAllocationCount": 0,
"nativeAllocationWeightTotal": null,
"pid": "7567",
"sampleCount": 5,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It looks like for some cases these stacks can get pretty long in a line. I don't have an idea to improve it though. I think that's still an improvement over the ones that we had before, especially since we couldn't see the stacks easily.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah. We can change it once it becomes a problem.

Comment thread src/test/fixtures/profile-summary.ts Outdated
);
}
const cat = markers.category[i];
if (cat < 0 || cat >= numCategories) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we should also check for null/undefined here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I went ahead and added checks for Number.isInteger everywhere.

mstange added 2 commits July 10, 2026 15:15
profile-conversion.test.ts was creating a snapshot file that was just a bunch
of raw profile JSONs, with around 900 000 lines total.

There's no way to catch regressions with such a test. Whenever we change the
shape of the tables in the profile format, it affects so many lines that
github's diff viewer will not render the diff, and you wouldn't be able to
meaningfully read it anyway.

For example, when I introduced the shared tables, I regressed the dhat
importer (it was overwriting some tables with empty tables), and I missed
the regression even though the test in theory "caught" it.

This commit replaces the raw profile snapshots with profile "summary"
snapshots. See the new snapshot file for examples. I think the new snapshots
are definitely more readable / reviewable, but there's also quite a bit of
new code to generate them. I'd be happy to cut back on the amount of detail
we collect when we make these summaries, to simplify that new code.
(Or maybe we can find a way to share some code with profiler-cli? Not sure.)

The new snapshot file is around 500 lines, and around 160 times smaller than
the old snapshot file.

As a second measure of defense, this commit also adds a generic profile
consistency checker function called `assertProfileIntegrity`. This would have
caught the dhat regression by itself, because nativeAllocations.stack[0] = 55
would have tripped over the stack table being empty.
@mstange
mstange force-pushed the push-lzsvmxpoywyu branch from fd7d04a to b33aa23 Compare July 10, 2026 21:10
@mstange
mstange enabled auto-merge July 10, 2026 21:11
@mstange
mstange merged commit 5fe8339 into firefox-devtools:main Jul 10, 2026
21 checks passed
@canova canova mentioned this pull request Jul 21, 2026
canova added a commit that referenced this pull request Jul 21, 2026
Changes:

[Sky Ning] Skip preview links for non-main PRs (#6161)
[spokodev] fix(gecko-upgrade): don't crash on a counter with empty
sample_groups (#6160)
[fatadel] Show counter values over time in profiler-cli (#6136)
[Markus Stange] Make profile-conversion snapshots more compact and
meaningful (#6152)
[Markus Stange] More typed arrays: sample + counter times, some
frametable columns (#6139)
[Nazım Can Altınova] Only render a marker url field as a link when the
whole value is a URL (#6163)
[fatadel] Show each counter's owning process in profiler-cli (#6164)
[Nazım Can Altınova] Document the pre-existing thread info and network
JSON schemas in the cli (#6171)
[Markus Stange] Copy column contents in
getRawSamplesTableBuilderFromExisting for consistency (#6168)
[Markus Stange] Convert eligible columns to typed arrays when outputting
from profiler-edit (#6167)
[Markus Stange] Remove unused samples.thread column (#6151)
[Markus Stange] Fixed botched merge which broke 'yarn ts' (#6174)
[Nazım Can Altınova] Add marker handles to `profiler-cli thread network`
(#6172)
[Markus Stange] Update json-slabs 0.3.0 → 0.4.0 (major) (#6176)
[Nazım Can Altınova] Surface network activity across profiler-cli
(#6175)
[Nazım Can Altınova] Add `profile meta` command to profiler-cli (#6177)
[Markus Stange] Allow raw marker table's `startTime` and `endTime`
columns to be Float64Array (#6169)
[nightcityblade] Fix light theme text selection colors (#6186)
[Nazım Can Altınova] Import source map URLs from Chrome DevTools traces
(#6190)
[Nazım Can Altınova] Rename yarn `build-profiler-cli` script to
`build-cli` (#6191)
[Nazım Can Altınova] Migrate husky to version 9 (#6201)
[Nazım Can Altınova] Fix horizontal overflow when the transform
navigator is long (#6199)
[fatadel] Add a 'hexadecimal' marker schema field format (#6197)
[Nazım Can Altınova] Bump source-map to 0.8.0 and remove the old type
workaround (#6202)
[Nazım Can Altınova] 🔃 Sync: l10n -> main (July 21, 2026) (#6209)


And special thanks to our localizers:

fr: parmegiani.thomas
fr: Théo Chevalier
sr: Марко Костић (Marko Kostić)
sv-SE: Luna Jernberg
tr: Grk
zh-CN: Ariel
zh-CN: Olvcpr423
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants