You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Document why Widget.operator== is marked as non-virtual #49490
Trying to override == on a widget triggers a warning, but there's no explanation on why (neither in the warning nor in the sources), and is not immediately obvious as to why we shouldn't do so.
I'm not sure why you'd want to override it though. Widgets are expected to be immutable. Even though Dart can't really guarantee immutability of e.g. a child list, the framework breaks if you mutate a property of the widget.
The default implementations of equals (i.e. identical) and hashCode (i.e. identityHashCode) should be good enough for that, and implementing it otherwise could slow things down when the framework goes to compare widgets in the tree.
Do we have any benchmarks for the leaf case? I wouldn't be surprised if the mere existence of that operator== made everything more expensive (since it turns a single-dispatch into a dynamic dispatch for every single widget comparison ever).
That could be confusing - someone expects the framework to be using their overridden ==, but it's actually just using identical and returning an unexpected result...
Regardless of what choice we make here (keeping nonVirtual, using identity) we won't be able to get away with documenting it extensively. equality as a concept is too heavily overloaded
I am pretty sure there are cases when Widget.operator== overriding is useful.
Consider an example: https://dartpad.dev/c20abd67d2cde74263ba1b49b368e062
There is a dynamic list of Items displayed in ListView. Overriding the operator== allows to avoid rebuilding all ItemViews in the viewport on Item addition, only a new one is built (or none if it happens outside the viewport).
This reduces worst frame build time from 25ms to less than 16ms on my device in profiling mode.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.
Activity
dnfield commentedon Jan 26, 2020
We should probably document this.
I'm not sure why you'd want to override it though. Widgets are expected to be immutable. Even though Dart can't really guarantee immutability of e.g. a child list, the framework breaks if you mutate a property of the widget.
The default implementations of equals (i.e.
identical) and hashCode (i.e. identityHashCode) should be good enough for that, and implementing it otherwise could slow things down when the framework goes to compare widgets in the tree./cc @Hixie @goderbauer who probably have more insight into this.
rrousselGit commentedon Jan 26, 2020
Flutter optimize rebuilds around the == operator.
Overriding == allows filtering rebuilds in situations that would otherwise rebuild for no reason.
It's mostly for leaf nodes though.
dnfield commentedon Jan 26, 2020
Can you give an example?
rrousselGit commentedon Jan 26, 2020
This makes the widget behaves like a
constinstance (don't rebuild if didn't change), but works with dynamic values.goderbauer commentedon Jan 27, 2020
Some context for why this was done is in the linked from the PR that added the
@nonVirtualannotation: #46900dnfield commentedon Jan 27, 2020
@goderbauer - I did look through that and saw a few places where @Hixie said not to do it, but never why.
rrousselGit commentedon Jan 27, 2020
It was likely about non-leaf widgets.
If a widget has a child, and that child too overrides ==, then we could end up effectively comparing the entire widget tree.
But I don't see any issue with leaf widgets though.
Hixie commentedon Jan 27, 2020
Do we have any benchmarks for the leaf case? I wouldn't be surprised if the mere existence of that operator== made everything more expensive (since it turns a single-dispatch into a dynamic dispatch for every single widget comparison ever).
jonahwilliams commentedon Jan 27, 2020
I think if we don't want developers to implement
Widget.==, we should just useidenticalinsteaddnfield commentedon Jan 27, 2020
That could be confusing - someone expects the framework to be using their overridden
==, but it's actually just usingidenticaland returning an unexpected result...jonahwilliams commentedon Jan 27, 2020
Regardless of what choice we make here (keeping nonVirtual, using identity) we won't be able to get away with documenting it extensively. equality as a concept is too heavily overloaded
jonahwilliams commentedon Jan 27, 2020
I meant "without" documenting it extensively
t-artikov commentedon Feb 9, 2020
I am pretty sure there are cases when
Widget.operator==overriding is useful.Consider an example: https://dartpad.dev/c20abd67d2cde74263ba1b49b368e062
There is a dynamic list of
Itemsdisplayed inListView. Overriding theoperator==allows to avoid rebuilding allItemViewsin the viewport on Item addition, only a new one is built (or none if it happens outside the viewport).This reduces worst frame build time from 25ms to less than 16ms on my device in profiling mode.
41 remaining items
github-actions commentedon Dec 24, 2021
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.