Skip to content

Scalable builds #3811

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

Open
davidmorgan opened this issue Feb 1, 2025 · 13 comments
Open

Scalable builds #3811

davidmorgan opened this issue Feb 1, 2025 · 13 comments
Labels
P1 A high priority bug; for example, a single project is unusable or has many test failures type-enhancement A request for a change that isn't a bug type-performance

Comments

@davidmorgan
Copy link
Contributor

The benchmark I'm adding in #3802 shows the problem pretty clearly,

json_serializable      
libraries clean/ms no changes/ms incremental/ms
1 21573 2840 4278
100 23040 2974 6327
250 28098 3285 12578
500 42940 4288 35061
750 69483 6561 67670
1000 115941 9178 119308

notice the incremental build time for 500 libraries and 1000 libraries: it increases from 35s to 119s, an increase of x3.4. For double the number of libraries the time increase should be x2 :)

The benchmark also runs for built_value, freezed and mockito, numbers on the PR, the story is pretty similar, except:

  • built_value and json_serializable are about 2x as slow as freezed on the big build, it turns out this is purely because they use shared parts, filed Faster shared parts #3803 for that sub-problem
  • mockito is about 2x as fast as freezed, I believe that is because mockito adds a part file to the test where it does not become a dep of all the other generators; conversely built_value, json_serializable and freezed all add part files in the app code, doubling the number of deps of all the generators

Apart from these multipliers the numbers are very similar, I think it does not matter much what the generators are actually doing.

@davidmorgan davidmorgan added type-enhancement A request for a change that isn't a bug type-performance P1 A high priority bug; for example, a single project is unusable or has many test failures labels Feb 1, 2025
@amrgetment

This comment has been minimized.

@davidmorgan

This comment has been minimized.

@amrgetment

This comment has been minimized.

@rrousselGit
Copy link

  • mockito is about 2x as fast as freezed, I believe that is because mockito adds a part file to the test where it does not become a dep of all the other generators; conversely built_value, json_serializable and freezed all add part files in the app code, doubling the number of deps of all the generators

Going back to this:

This could be because freezed starts by asking for the AST of the generated file.
I need the AST, and build_runner doesn't give it to me. So I have to ask for it again. And I don't think it's cached, right?

If build_runner could expose us the AST, that'd be cool. Most of my generators use it.

@davidmorgan
Copy link
Contributor Author

  • mockito is about 2x as fast as freezed, I believe that is because mockito adds a part file to the test where it does not become a dep of all the other generators; conversely built_value, json_serializable and freezed all add part files in the app code, doubling the number of deps of all the generators

Going back to this:

This could be because freezed starts by asking for the AST of the generated file. I need the AST, and build_runner doesn't give it to me. So I have to ask for it again. And I don't think it's cached, right?

If build_runner could expose us the AST, that'd be cool. Most of my generators use it.

The performance issue I'm looking at is just due to the deps graph, it's nothing to do with what the generator does. When you look at the CPU flame charts of the large benchmarks, the generator barely shows up.

Once that's solved--yes, I think there's a possibility of handling ASTs better/faster, we'd have to compare :) thanks.

@t-beckmann
Copy link

+1 Just to let you know, this is an issue for me as I have a CI pipeline taking more than an hour to generate. Glad you are working on this!

@jonpittock
Copy link

definite issue for us. Big project. Mono repo. Almost unusable!

@esDotDev
Copy link

The other problem this shows is how slow the baseline performance levels are. 22s for first-run, and 6 seconds for incremental, with a single library, feel at least 10x bigger than they should be if we're going to get anything near the performance level of built-in data classes, or what was imagined w/ macros.

@davidmorgan
Copy link
Contributor Author

@esDotDev yes, for sure.

You get quite a lot faster small incremental builds if you use watch mode; I'm not sure yet how much people are forced to use build or are not aware of watch, but ideally I'd like repeated use of build to be just as fast as watch. And for both to be faster than today :)

Filed #4019 for performance improvements for small builds.

Thanks :)

@rrousselGit
Copy link

IMO clean build speed is not nearly as important as the other two columns

It's important, don't mind me. But clean build can be multiple orders of magnitude slower than incremental builds.

Take flutter run.
The commend takes easily 10s of seconds to start the app. That's your "clean build".
But once started, hotreload takes a few milliseconds. That's your incremental build


For that reason, I feel like there's a missed opportunity by not investigating better cache invalidation strategies.

It's cool that we're trying to make writing 1000 files fast.
But more often than not, we should just be writing 1 file instead of 1000

@davidmorgan
Copy link
Contributor Author

For that reason, I feel like there's a missed opportunity by not investigating better cache invalidation strategies.

There's an arc of work happening over in the analyzer to support fine-grained invalidation there

https://dart-review.googlesource.com/q/Fine.

which I expect will help significantly, possibly with some changes on the build_runner side too, we'll see.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P1 A high priority bug; for example, a single project is unusable or has many test failures type-enhancement A request for a change that isn't a bug type-performance
Projects
None yet
Development

No branches or pull requests

6 participants