-
-
Notifications
You must be signed in to change notification settings - Fork 116
perf: improve equality comparison performance #173
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
Merged
felangel
merged 17 commits into
felangel:master
from
Maksimka101:feat/performance-improvement
Nov 21, 2024
Merged
Changes from 2 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
991cebf
Feat: improve comparison performance
Maksimka101 6204491
Feat: optimize non collection properties comparison
Maksimka101 45a0377
Refactor: move comparison logic back to the `equatable_utils.dart` file
Maksimka101 88052e1
Fix: sets comparison
Maksimka101 312a2a8
Style: reformat code
Maksimka101 c3f4aef
Fix: sets comparison in the `_objectsEquals` function
Maksimka101 725f521
refactor: minor updates to code consistency
felangel b21514f
Merge branch 'master' into feat/performance-improvement
felangel 8d283b0
refactor: simplify `equals` implementation and fix coverage
felangel 6ab28df
chore: update benchmarks
felangel fed7e05
chore: adjust comments
felangel 3f5afff
refactor: simplify equatable utils
felangel 261a28b
Fix the `setEquals` function and write tests for the `*Equals` functions
Maksimka101 751a2b0
Inline the `_isEquatable` and `objectsEquals` functions to improve pe…
Maksimka101 29e6c77
Merge branch 'master' into feat/performance-improvement
felangel bed68af
chore: update benchmark results
felangel 9e0983b
chore: minor adjustments
felangel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| import 'package:equatable/src/equatable.dart'; | ||
| import 'package:equatable/src/equatable_mixin.dart'; | ||
|
|
||
| /// Determines whether [list1] and [list2] are equal. | ||
| // This method is optimized for comparing properties | ||
| // from primitive types like int, double, String, bool. | ||
| // Using the _iterableEquals method instead of this code | ||
| // can degrade performance by ~ 20%. | ||
| bool equals(List<Object?> list1, List<Object?> list2) { | ||
| if (identical(list1, list2)) return true; | ||
| final length = list1.length; | ||
| if (length != list2.length) return false; | ||
|
|
||
| for (var i = 0; i < length; i++) { | ||
| final unit1 = list1[i]; | ||
| final unit2 = list2[i]; | ||
|
|
||
| if (_isEquatable(unit1) && _isEquatable(unit2)) { | ||
| if (unit1 != unit2) return false; | ||
| } else if (unit1 is Iterable && unit2 is Iterable) { | ||
| return _iterableEquals(unit1, unit2); | ||
| } else if (unit1 is Set && unit2 is Set) { | ||
| return _setEquals(unit1, unit2); | ||
| } else if (unit1 is Map && unit2 is Map) { | ||
| return _mapEquals(unit1, unit2); | ||
| } else if (unit1?.runtimeType != unit2?.runtimeType) { | ||
| return false; | ||
| } else if (unit1 != unit2) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool _objectsEquals(Object? object1, Object? object2) { | ||
| if (identical(object1, object2)) { | ||
| return true; | ||
| } else if (_isEquatable(object1) && _isEquatable(object2)) { | ||
| if (object1 != object2) return false; | ||
| } else if (object1 is List && object2 is List) { | ||
| return _iterableEquals(object1, object2); | ||
| } else if (object1 is Set && object2 is Set) { | ||
| return _setEquals(object1, object2); | ||
| } else if (object1 is Map && object2 is Map) { | ||
| return _mapEquals(object1, object2); | ||
| } else if (object1?.runtimeType != object2?.runtimeType) { | ||
| return false; | ||
| } else if (object1 != object2) { | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool _isEquatable(Object? object) { | ||
| return object is Equatable || object is EquatableMixin; | ||
| } | ||
|
|
||
| bool _setEquals(Set<Object?> a, Set<Object?> b) { | ||
| if (a.length != b.length) return false; | ||
| if (identical(a, b)) return true; | ||
| for (final element in a) { | ||
| if (!b.contains(element)) return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool _iterableEquals(Iterable<Object?> a, Iterable<Object?> b) { | ||
| if (identical(a, b)) return true; | ||
| final aLength = a.length; | ||
| if (aLength != b.length) return false; | ||
| for (var i = 0; i < aLength; i++) { | ||
| if (!_objectsEquals(a.elementAt(i), b.elementAt(i))) return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool _mapEquals(Map<Object?, Object?> a, Map<Object?, Object?> b) { | ||
| if (a.length != b.length) return false; | ||
| if (identical(a, b)) return true; | ||
| for (final key in a.keys) { | ||
| if (!_objectsEquals(a[key], b[key])) return false; | ||
| } | ||
| return true; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.