freezed icon indicating copy to clipboard operation
freezed copied to clipboard

Large components cause the process to freeze

Open medz opened this issue 1 year ago • 29 comments

  • odroe/prisma-dart#99

When I switched from json_serializable to freezed, I encountered performance problems that allowed the process of dart run build_runner build to freeze.

I don't know if it's a problem with freezed or build_runner, but I'm sure I just use json_serializable and no such problem occurs.

The simplest complex warehouse: https://github.com/odroe/prisma-dart/tree/main/example/simple

Download it, run dart run orm generate, which builds a large template class file that depends on freezed.

Then run dart run build_runner build, there will be a freeze during the running process (as the content of lib/prisma_client.dart increases, the freeze time is getting longer and longer.

until it appears:

[WARNING] No actions completed for 10m 3s, waiting on:
   - frozen on lib/prisma_client.dart

such a warning before continuing.

medz avatar Jan 10 '23 09:01 medz

image

This file also has at least 8,000 lines of code, and if more data tables are defined, it will exceed 10,000 lines. There are at least a few hundred boilerplate definitions for freezed.

medz avatar Jan 10 '23 09:01 medz

@rrousselGit Is it possible for us to use a more efficient way to build the resulting code?

I read the source code of freezed and the way it structures the code is inefficient, which I guess is one of the reasons for this performance problem.

When I was developing Prisma ORM for Dart, I used code_builder to generate Dart code and write all files into a single library file, which is a very large collection of Dart code, which can be completed in less than 1 second .

medz avatar Jan 10 '23 10:01 medz

I read the source code of freezed and the way it structures the code is inefficient

What is inefficient?

I could be wrong, but I highly doubt Freezed is the one locking for 10mn here. I've generated files of comparable length is milliseconds before.

I don't really have time to investigate this. If it matters to you, it'd be great if you could give it a look yourself and share your results :)

rrousselGit avatar Jan 10 '23 10:01 rrousselGit

@rrousselGit Sorry, it may be that my inaccurate words have caused you to misunderstand (I need to rely on translation software, it may be that the result of the translation software translation is wrong)

Well, I know you're busy. This issue is really presumptuous. But I don't know how to do performance analysis in Dart, so I don't know what method to use to locate this problem.

I'll try it, if it fails. I'll tell consumers of my package to live with it, then I'll start the migration to Dart 3 support, and then completely remove anything from the build ecosystem from my library.

medz avatar Jan 10 '23 10:01 medz

One thing you can try is adding a Stopwatch around the gneerate method inside Freezed and see how long it takes. It should give you an estimate of whether freezed is the problem or not.

But my guess is that this is coming from build.

rrousselGit avatar Jan 10 '23 10:01 rrousselGit

image image image

emmm, maybe this is really caused by freezed. A single file with a total of 275 freezed boilerplate code. freezed took 55 seconds to complete the task. The entire build process including json_serializable took a total of 67 seconds, that is to say, build_runner took three seconds to process tasks, json_serializable took 9 seconds to process tasks, and freezed accounted for 82% mission time.

medz avatar Jan 10 '23 10:01 medz

@rrousselGit

medz avatar Jan 10 '23 10:01 medz

Hum, we're nowhere near the 10minutes mark you mentioned before.

But maybe something could be improved. Still, I'm quite busy and don't really and a problem with it. If you could have a look, it would be lovely. Otherwise I don't promise I'll be able to have a look any time soon

rrousselGit avatar Jan 10 '23 11:01 rrousselGit

But note that this isn't quite where I would put the StopWatch, as this includes the analyzer work (which is more of a build_runner thing than a freezed thing)

Try putting it in ParserGenerator's generate. After the libraryFor line (which is the analyzer stuff)

rrousselGit avatar Jan 10 '23 11:01 rrousselGit

Hum, we're nowhere near the 10minutes mark you mentioned before.

Mentioned here is a table with more than five and a moderate number of fields. What I tested here is that I just wrote a very simple data table and then used it to generate Dart classes. (The purpose is to speed up my test time)

Also, I'll find some time to see how to optimize this problem. My development tasks are too heavy to write 16 to 18 hours of code every day.

medz avatar Jan 10 '23 11:01 medz

image image

Try putting it in ParserGenerator's generate. After the libraryFor line (which is the analyzer stuff)

It seems to be the same, maybe we have to solve it from the root cause.

medz avatar Jan 10 '23 11:01 medz

https://github.com/medz/freezed/tree/big-test

medz avatar Jan 10 '23 11:01 medz

Seeing this happen consistently now with large union classes (over 50 unions) on the latest flutter stable version. Last code gen took 30 minutes to complete. Before upgrading flutter it was taking 2 minutes. I've migrated freezed away from my large union class and and it fixed the issue. Would be nice to see this resolved though.

BWhiteApps avatar Apr 16 '23 19:04 BWhiteApps

when wait fix?

Nightwelf avatar Apr 28 '23 10:04 Nightwelf

I am also experiencing this issue after upgrading to the latest version of Flutter on stable (3.10.5). Code generation used to generally complete in ~3min with Flutter 3.3 – it now takes ~20min.

I have been able to pin down the issue to freezed file generation by excluding the freezed builder from my build.yaml, and observing how the build completes in a significantly shorter amount of time as a result.

karimafas avatar Jun 23 '23 10:06 karimafas

In a package, we have 20~ union classes with 20~ constructors in each. Total 150-200 constructors.

Upgrading from Flutter 3.7.1 and freezed 2.1.0 to Flutter 3.10.5 and freezed 2.3.5 caused freezed code generation to slow down from 30~ seconds to 5+ mins.

benfgit avatar Jun 28 '23 20:06 benfgit

Seems related to https://github.com/rrousselGit/freezed/issues/804

benfgit avatar Jun 28 '23 20:06 benfgit

A significant rewrite of Freezed is in progress. So we'll see how this issue is impacted after those changes.

rrousselGit avatar Jun 29 '23 09:06 rrousselGit

Upgrading from Flutter 3.7.1 and freezed 2.1.0 to Flutter 3.10.5 and freezed 2.3.5 caused freezed code generation to slow down from 30~ seconds to 5+ mins.

60+ enums upgrade to Flutter 3.10.5 and freezed 2.3.5 time changed from 7+ mins to 11 sec !!!

dependencies:
  freezed_annotation: ^2.2.0
  json_annotation: ^4.8.1
dev_dependencies:
  json_serializable: ^6.7.0
  freezed: ^2.3.5
  build_runner: ^2.4.5
> dart run build_runner build --delete-conflicting-outputs
[INFO] Generating build script completed, took 224ms
[INFO] Reading cached asset graph completed, took 78ms
[INFO] Checking for updates since last build completed, took 412ms
[INFO] Running build completed, took 12.3s
[INFO] Caching finalized dependency graph completed, took 28ms
[INFO] Succeeded after 11.3s with 21 outputs (22 actions)

Nightwelf avatar Jun 29 '23 09:06 Nightwelf

@Nightwelf You mean that things are much faster for you now?

rrousselGit avatar Jun 29 '23 09:06 rrousselGit

@rrousselGit yes!

Nightwelf avatar Jun 29 '23 09:06 Nightwelf

@Nightwelf do you have any codegen classes other than enums that may effect the total time?

Is it possible that the build_runner did not generate anything due to files being already generated? Can you perform the benchmark with all of the .freezed.dart files deleted?

This command deletes all of them under the current directory find . -type f -name "*.freezed.dart" -delete.

benfgit avatar Jun 29 '23 10:06 benfgit

@benfgit before that i deleted all the files, then i got a list like this

image

Nightwelf avatar Jun 29 '23 10:06 Nightwelf

@rrousselGit Clearing all of the pubspec.lock files in project (main package and all of the sub packages that it depends) and regenerating them fixed the issue. Codegen is as fast as before now ✅

benfgit avatar Jun 30 '23 12:06 benfgit

Looks like that was a performance regression on a transitive dependency then, not Freezed itself.

I assume that the fix is a simple dart pub upgrade

rrousselGit avatar Jun 30 '23 13:06 rrousselGit

Deleting pubspec.lock on the top level of my project as well as all nested packages and regenerating worked for me too. Cheers @benfgit! File generation time was reduced to ~2min 🎉

karimafas avatar Jul 03 '23 15:07 karimafas

@rrousselGit I suggest to rename this issue as "Freezed generation takes longer when Flutter is updated" to reach more people who are having the same issue.

benfgit avatar Jul 03 '23 16:07 benfgit

Folks seem to be finding this issue just fine. But it appears that the problem went away anyway?

If the problem is fixed, we likely can close this.

rrousselGit avatar Jul 03 '23 18:07 rrousselGit

Folks seem to be finding this issue just fine. But it appears that the problem went away anyway?

If the problem is fixed, we likely can close this.

Still have significant build times of 15 Minutes but this is due to build_runner being flawed, I guess? Would love to see an update on build times tho, hyped for the rewrite!

flawnn avatar Jan 08 '24 14:01 flawnn