Closed phamnhuvu-dev closed 5 years ago
@johnpryan Please help me review it.
I don't think this package should assume how users want to compare state objects. If this is something you need, why not compare using the hash code in your ==
method?
why not compare using the hash code in your
==
method?
@johnpryan I have an example with the state have a list variable:
import 'package:equatable/equatable.dart';
class A extends Equatable {
final List<int> list;
A({this.list}) : super([list]);
A copyWith({List<int> list}) {
return A(list: list ?? this.list);
}
}
A reducerUpdateList_1(A state) {
// Update list
List<int> list = state.list;
list.add(10);
return state.copyWith(list: list);
}
A reducerUpdateList_2(A state) {
// Update list from new List is created by `List.from`
List<int> list = List.from(state.list);
list.add(10);
return state.copyWith(list: list);
}
My expect is after list updated something in its an element, The compare return false without creating new instance list..
Compare by "==" operator
void main() {
A _state1 = A(list: List());
final state1 = reducerUpdateList_1(_state1);
print(_state1 == state1); // return true;
A _state2 = A(list: List());
final state2 = reducerUpdateList_2(_state2); // Create new List by List.from()
print(_state2 == state2); // return false;
}
Compare by hashCode
void main() {
A _state1 = A(list: List());
final oldHashCode = _state1.hashCode;
final state1 = reducerUpdateList_1(_state1);
print(oldHashCode == state1.hashCode); // return false;
}
Benchmark between Compare by "==" operator with Create new List by List.from() and Compare by hashCode
// A list 100000000 item
List<int> getList() {
List<int> list = List();
for (int i = 0; i < 100000000; i++) {
list.add(i);
}
return list;
}
void main() {
A _state1 = A(list: getList());
// Start time
int time1 = getCurrentTime();
final oldHashCode = _state1.hashCode;
final state1 = reducerUpdateList_1(_state1);
print(oldHashCode == state1.hashCode); // return false;
int time2 = getCurrentTime();
print(time2 - time1);
A _state2 = A(list: getList());
// Start time
int time3 = getCurrentTime();
final state2 = reducerUpdateList_2(_state2);
print(_state2 == state2); // return false;
int time4 = getCurrentTime();
print(time4 - time3);
}
The time check different by hashCode: ~1600 The time check different by creating new List: ~3700
Override hashCode
method:
https://github.com/felangel/equatable/blob/master/lib/src/equatable_utils.dart#L3-L24
I updated Benchmark between Compare by "==" operator with Create new List by List.from() and Compare by hashCode. @johnpryan Please help me review it.
It looks like package:equatable
overrides ==
and =hashCode
. If you are seeing better performance comparing hashCodes you could just compare hashCodes that in your ==
method instead.
operator ==(Object other) {
return other.hashCode == hashCode;
}
We need to receive changed state when update collection variables(List, Map, .v.v...) same reference. All are ok if I clone collection variables are like
List.from()
but the complex time is O(n). It isn't good for the performance of large collection variablesSo I get hashCode before state pass to reducers then compares with new hashCode after update collection variables.
Please check my repo to see different between redux: 3.0.0 and my contribution.
Check redux:3.0.0 please comment dependency_overrides then run flutter packages get Check my contribution please uncomment dependency_overrides then run flutter packages get
https://github.com/phamnhuvu-dev/flutter_card_list_redux