Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: Fix edge-case slowdown in compilation #942

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

nmn
Copy link
Contributor

@nmn nmn commented Mar 11, 2025

What changed / motivation ?

Identified and fixed a bad edge-case where using certain patterns of constants would take an unreasonable amount of time to compile.

Created a fixture with the problematic code pattern, and added a new jest to to verify that it compiles.

Before the fix, the test that transforms this one file took ~100s on an M1 Max.

After the fix, it dropped to ~1s.

i.e. That is a 100x perf improvement for this particular pattern of code.

TLDR;

Object evaluation wasn't being cached properly.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 11, 2025
Copy link

github-actions bot commented Mar 11, 2025

workflow: benchmarks/size

Comparison of minified (terser) and compressed (brotli) size results, measured in bytes. Smaller is better.

benchmarks@0.11.1 size:compare
node size/compare.js /tmp/tmp.yqCj4nwFe2 /tmp/tmp.LzadMsP5lR

Results Base Patch Ratio
stylex/lib/stylex.js
· compressed 985 985 1.00
· minified 3,154 3,154 1.00
stylex/lib/StyleXSheet.js
· compressed 1,266 1,266 1.00
· minified 3,776 3,776 1.00
benchmarks/size/.build/bundle.js
· compressed 537,611 537,611 1.00
· minified 7,435,904 7,435,904 1.00
benchmarks/size/.build/stylex.css
· compressed 100,609 100,609 1.00
· minified 755,721 755,721 1.00

@nmn nmn requested review from necolas and mellyeliu March 11, 2025 11:27
const themeFile = path.resolve(__dirname, '../__fixtures__/colorThemes.js');

describe('create theme', () => {
it('transform complex theme file', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
it('transform complex theme file', () => {
test('transform complex theme file', () => {


function transform(file, opts = defaultOpts) {
const result = transformFileSync(file, {
filename: opts.filename || '/stylex/packages/TestTheme.stylex.js',
Copy link
Contributor

Choose a reason for hiding this comment

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

Having a fake default filename here is a bit confusing, esp since we're passing in a "theme" in the test but the fallback is "Theme.stylex.js" which is a file suffix typically used for files containing defineVars exports

@@ -0,0 +1,48 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain what this test is for? I thought we already had unit tests for theme creation. This is a unit test, so doesn't benchmark anything. If we want a perf benchmark, we should add to the benchmarks instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added it as a test as I was trying to debug the root cause of the slowdown. It's not quite a benchmark, it's just a verification that the transformation isn't taking an unreasonably long amount of time.

I'm open to suggestions on how exactly to define this. It could be a benchmark, but I'm not sure what that would look like.

Copy link
Contributor

Choose a reason for hiding this comment

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

No worries, I'll have a go at converting this into a benchmark next week

keyPath,
state.traversalState,
state.functions,
state.seen,
Copy link
Member

Choose a reason for hiding this comment

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

is the edge case that we weren't properly checking the value of seen here? can we update the summary to include more details

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The edge-case is that we were re-computing objects over and over again previously.

The change adds caching to avoid doing that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants