Skip to content
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

should compare by hashCode. #48

Closed
wants to merge 1 commit into from

Conversation

phamnhuvu-dev
Copy link

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 variables

So 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

@phamnhuvu-dev
Copy link
Author

@johnpryan Please help me review it.

@johnpryan
Copy link
Collaborator

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?

@phamnhuvu-dev
Copy link
Author

phamnhuvu-dev commented Jun 2, 2019

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

@phamnhuvu-dev
Copy link
Author

@phamnhuvu-dev
Copy link
Author

I updated Benchmark between Compare by "==" operator with Create new List by List.from() and Compare by hashCode.
@johnpryan Please help me review it.

@johnpryan
Copy link
Collaborator

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;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants