optimize GetBuilder "group id" using `HashSet`
- `Changed HashMap<int,GetStateUpdate>` to `HashSet<GetStateUpdate>`. Reference https://github.com/jonataslaw/getx/pull/565#discussion_r484088390 - Added a internal VoidCallback in `GetStateUpdaterMixin::getUpdate`, to see if it reduces overhead of anonym function in `setState()` (considering GC).
Showing
1 changed file
with
28 additions
and
27 deletions
@@ -12,7 +12,9 @@ import 'simple_builder.dart'; | @@ -12,7 +12,9 @@ import 'simple_builder.dart'; | ||
12 | //typedef Disposer = void Function(); | 12 | //typedef Disposer = void Function(); |
13 | 13 | ||
14 | // replacing StateSetter, return if the Widget is mounted for extra validation. | 14 | // replacing StateSetter, return if the Widget is mounted for extra validation. |
15 | +// if it brings overhead the extra call, | ||
15 | typedef GetStateUpdate = bool Function(); | 16 | typedef GetStateUpdate = bool Function(); |
17 | +//typedef GetStateUpdate = void Function(VoidCallback fn); | ||
16 | 18 | ||
17 | /// Complies with [GetStateUpdater] | 19 | /// Complies with [GetStateUpdater] |
18 | /// | 20 | /// |
@@ -24,9 +26,14 @@ typedef GetStateUpdate = bool Function(); | @@ -24,9 +26,14 @@ typedef GetStateUpdate = bool Function(); | ||
24 | /// TODO: check performance HIT for the extra method call. | 26 | /// TODO: check performance HIT for the extra method call. |
25 | /// | 27 | /// |
26 | mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> { | 28 | mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> { |
29 | + // To avoid the creation of an anonym function to be GC later. | ||
30 | + static VoidCallback _stateCallback = () {}; | ||
31 | + | ||
32 | + /// Experimental method to replace setState((){}); | ||
33 | + /// Used with GetStateUpdate. | ||
27 | bool getUpdate() { | 34 | bool getUpdate() { |
28 | final _mounted = mounted; | 35 | final _mounted = mounted; |
29 | - if (_mounted) setState(() {}); | 36 | + if (_mounted) setState(_stateCallback); |
30 | return _mounted; | 37 | return _mounted; |
31 | } | 38 | } |
32 | } | 39 | } |
@@ -37,10 +44,7 @@ class GetxController extends DisposableInterface { | @@ -37,10 +44,7 @@ class GetxController extends DisposableInterface { | ||
37 | // final _updatersIds = HashMap<String, StateSetter>(); //<old> | 44 | // final _updatersIds = HashMap<String, StateSetter>(); //<old> |
38 | final _updatersIds = HashMap<String, GetStateUpdate>(); | 45 | final _updatersIds = HashMap<String, GetStateUpdate>(); |
39 | 46 | ||
40 | -// final _updatersGroupIds = HashMap<String, List>(); //<old> | ||
41 | - final _updatersGroupIds = HashMap<String, HashMap<int, GetStateUpdate>>(); | ||
42 | - | ||
43 | - static int _groupIdCount = 0; | 47 | + final _updatersGroupIds = HashMap<String, HashSet<GetStateUpdate>>(); |
44 | 48 | ||
45 | /// Rebuilds [GetBuilder] each time you call [update()]; | 49 | /// Rebuilds [GetBuilder] each time you call [update()]; |
46 | /// Can take a List of [ids], that will only update the matching | 50 | /// Can take a List of [ids], that will only update the matching |
@@ -50,14 +54,21 @@ class GetxController extends DisposableInterface { | @@ -50,14 +54,21 @@ class GetxController extends DisposableInterface { | ||
50 | void update([List<String> ids, bool condition = true]) { | 54 | void update([List<String> ids, bool condition = true]) { |
51 | if (!condition) return; | 55 | if (!condition) return; |
52 | if (ids == null) { | 56 | if (ids == null) { |
53 | -// _updaters.forEach((rs) => rs(() {}));//<old> | 57 | +// _updaters?.forEach((rs) => rs(() {})); //<old> |
54 | _updaters.forEach((rs) => rs()); | 58 | _updaters.forEach((rs) => rs()); |
55 | } else { | 59 | } else { |
56 | - ids.forEach((element) { | ||
57 | -// _updatersGroupIds[element]?.forEach((k, rs) => rs(() {}));//<old> | ||
58 | -// _updatersIds[element]?.call(() {});//<old> | ||
59 | - _updatersIds[element]?.call(); | ||
60 | - _updatersGroupIds[element]?.forEach((k, rs) => rs()); | 60 | + // @jonny, remove this commented code if it's not more optimized. |
61 | +// for (final id in ids) { | ||
62 | +// if (_updatersIds[id] != null) _updatersIds[id](); | ||
63 | +// if (_updatersGroupIds[id] != null) | ||
64 | +// for (final rs in _updatersGroupIds[id]) rs(); | ||
65 | +// } | ||
66 | + | ||
67 | + ids.forEach((id) { | ||
68 | +// _updatersIds[id]?.call(() {}); //<old> | ||
69 | +// _updatersGroupIds[id]?.forEach((rs) => rs(() {})); //<old> | ||
70 | + _updatersIds[id]?.call(); | ||
71 | + _updatersGroupIds[id]?.forEach((rs) => rs()); | ||
61 | }); | 72 | }); |
62 | } | 73 | } |
63 | } | 74 | } |
@@ -72,13 +83,10 @@ class GetxController extends DisposableInterface { | @@ -72,13 +83,10 @@ class GetxController extends DisposableInterface { | ||
72 | VoidCallback addListenerId(String key, GetStateUpdate listener) { | 83 | VoidCallback addListenerId(String key, GetStateUpdate listener) { |
73 | // _printCurrentIds(); | 84 | // _printCurrentIds(); |
74 | if (_updatersIds.containsKey(key)) { | 85 | if (_updatersIds.containsKey(key)) { |
75 | - final _innerKey = _groupIdCount++; | ||
76 | -// final _ref = _updatersGroupIds[key] ??= HashMap<int, StateSetter>();//<old> | ||
77 | - final _ref = _updatersGroupIds[key] ??= HashMap<int, GetStateUpdate>(); | ||
78 | - _ref[_innerKey] = listener; | 86 | + _updatersGroupIds[key] ??= HashSet<GetStateUpdate>.identity(); |
87 | + _updatersGroupIds[key].add(listener); | ||
79 | return () { | 88 | return () { |
80 | - _ref?.remove(_innerKey); | ||
81 | -// _printCurrentIds(); | 89 | + _updatersGroupIds[key].remove(listener); |
82 | }; | 90 | }; |
83 | } else { | 91 | } else { |
84 | _updatersIds[key] = listener; | 92 | _updatersIds[key] = listener; |
@@ -148,10 +156,6 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -148,10 +156,6 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
148 | with GetStateUpdaterMixin { | 156 | with GetStateUpdaterMixin { |
149 | GetxController controller; | 157 | GetxController controller; |
150 | bool isCreator = false; | 158 | bool isCreator = false; |
151 | - | ||
152 | - /// TODO: @jonny, you intend to use disposers? | ||
153 | -// final HashSet<Disposer> disposers = HashSet<Disposer>(); | ||
154 | - | ||
155 | VoidCallback remove; | 159 | VoidCallback remove; |
156 | 160 | ||
157 | @override | 161 | @override |
@@ -195,8 +199,8 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -195,8 +199,8 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
195 | void _subscribeToController() { | 199 | void _subscribeToController() { |
196 | remove?.call(); | 200 | remove?.call(); |
197 | remove = (widget.id == null) | 201 | remove = (widget.id == null) |
198 | -// ? controller?.addListener(setState)//<old> | ||
199 | -// : controller?.addListenerId(widget.id, setState);//<old> | 202 | +// ? controller?.addListener(setState) //<old> |
203 | +// : controller?.addListenerId(widget.id, setState); //<old> | ||
200 | ? controller?.addListener(getUpdate) | 204 | ? controller?.addListener(getUpdate) |
201 | : controller?.addListenerId(widget.id, getUpdate); | 205 | : controller?.addListenerId(widget.id, getUpdate); |
202 | } | 206 | } |
@@ -218,10 +222,6 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -218,10 +222,6 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
218 | } | 222 | } |
219 | } | 223 | } |
220 | remove?.call(); | 224 | remove?.call(); |
221 | - | ||
222 | -// disposers.forEach((element) { | ||
223 | -// element(); | ||
224 | -// }); | ||
225 | } | 225 | } |
226 | 226 | ||
227 | @override | 227 | @override |
@@ -251,6 +251,7 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | @@ -251,6 +251,7 @@ class _GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> | ||
251 | /// like Rx() does with Obx(). | 251 | /// like Rx() does with Obx(). |
252 | class Value<T> extends GetxController { | 252 | class Value<T> extends GetxController { |
253 | Value([this._value]); | 253 | Value([this._value]); |
254 | + | ||
254 | T _value; | 255 | T _value; |
255 | 256 | ||
256 | T get value { | 257 | T get value { |
-
Please register or login to post a comment