Closed SecondFlight closed 2 years ago
Hello!
Tha ms for the detailed report. My immediate guess is that it could be related to immutable collections.
I'm not sure if I'll be able to check that today, so try disabling it and see if the issue disappears 😊
Thanks for the quick reply and the suggestion! Adding makeCollectionsUnmodifiable: false
to the @Freezed
annotation does seem to fix the issue, so I'm using it as a workaround for now.
// Workaround for https://github.com/rrousselGit/freezed/issues/653
@Freezed(makeCollectionsUnmodifiable: false)
class MyModel with _$MyModel {
// ...
Thinking about this issue, I think it may be worth disabling this feature in release mode
As in, before making a release build, do:
dart run build_runner build --release
which would generate the Freezed files again, but with makeCollectionsUnmodifiable
disabled.
For reference, you can do this --release
thing today:
targets:
$default:
builders:
freezed:
release_options:
make_collections_unmodifiable: false
What about in packages? I maintain a client package for a HTTP API with a lot of Freezed models exposed in the package API.
Ideally, I'd like collections to be unmodifiable to users of the package. There's no easy way for them to rebuild the package files in release mode, though.
To add some more context to this, it might really be a worthwhile optimization to try to avoid DeepCollectionEquality when possible.
It is ~5x slower than ListEquality() in simple cases, and has quadratic complexity when the collection is actually nested ( O(n^2) runtime, where n is the level of nesting in the collection).
So, a JSON Map<String, dynamic> with nesting level of 3 in a freezed object already takes ~60x longer to compare using ==
than an optimized version.
See this tracking issue: https://github.com/dart-lang/collection/issues/263
and benchmark that I wrote: https://github.com/knaeckeKami/json_equals
And, as Jake Wharton puts it,
A code generator is only written once but the code it generates occurs many times. Thus, any investment into making the generator emit more efficient code will pay for itself very quickly. This generally means output less code and allocate fewer objects wherever possible. I’d like to expand on that with two specific, real-world examples which I’ve run into.
Yes, there is an issue about it.
I just don't care too much about it, as Freezed will have to be rewritten soon with metaprogramming.
sorry, yeah I did not mean to comment on this closed issue, i copied it in the open issue.
I just don't care too much about it, as Freezed will have to be rewritten soon with metaprogramming.
Fair enough, I just wanted to bring some attention to it that someone might run into this (I ran into this in a app of mine and was not aware of the quadratic complexity of deepcollectionequality so I took me some time to figure out was was going on)
Hi, thanks for the library! I have greatly appreciated using it.
After updating
freezed
to 2.0, my Flutter app has seen a significant performance regression that worsens over time.I have not been able to find this reported anywhere else, though I apologize if I've missed something. I believe this differs from #626 as that report is talking in general about the performance of
DeepCollectionEquality
and doesn't mention deteriorating performance over time.Reproduction
I believe I've isolated a minimal reproduction case. Here's a code sample:
myModel.dart
:main.dart
:Expected behavior
I expect the
print
statement to display a relatively constant time throughout the duration of the loop, no matter how slow or fast.Actual behavior
When using
freezed: ^1.1.0
, I get an output like this:The average duration does not appear to change significantly over time.
When running with
freezed: ^2.0.2
, I get an output like this:The delta continues to increase over time. Most of the time here seems to be spent in the
oldModel == model
equality check. Commenting it out results in this output (using^2.0.2
):