Skip to content

Conversation

@ShakyaCsun
Copy link

Status

IN DEVELOPMENT

Breaking Changes

YES

Description

Add support for equality comparison between all types of Iterable including Sets to iterableEquals and subsequently all Equatable objects.
Additionally, a propsEquals function which compares the List<Object?> props is added and used in operator == override for Equatable and EquatableMixin in place of iterableEquals to skip the newly added checks and maintain similar performance in the existing benchmarks.

Fixes #196

Impact to Remaining Code Base

This PR will affect:

  • Equality checking between non-Set Iterable and Set.
    • returns false instead of throwing AssertionError
  • Equality checking between a List and a Iterable of equal elements in same order.
    • returns false instead of true
Benchmarks result from before and after

EmptyEquatable

stat Before After
total runs 1 759 499 1 743 908
total time 2.0000 s 2.0000 s
average run 1 μs 1 μs
runs/second 1 000 000 1 000 000
units 100 100
units/second 100 000 000 100 000 000
time per unit 0.0100 μs 0.0100 μs

PrimitiveEquatable

stat Before After
total runs 520 591 519 660
total time 2.0000 s 2.0000 s
average run 3 μs 3 μs
runs/second 333 333 333 333
units 100 100
units/second 33 333 333 33 333 333
time per unit 0.0300 μs 0.0300 μs

CollectionEquatable (static, small)

stat Before After
total runs 89 451 75 242
total time 2.0000 s 2.0000 s
average run 22 μs 26 μs
runs/second 45 455 38 462
units 100 100
units/second 4 545 455 3 846 154
time per unit 0.2200 μs 0.2600 μs

CollectionEquatable (static, medium)

stat Before After
total runs 59 444 67 114
total time 2.0000 s 2.0000 s
average run 33 μs 29 μs
runs/second 30 303 34 483
units 100 100
units/second 3 030 303 3 448 276
time per unit 0.3300 μs 0.2900 μs

CollectionEquatable (static, large)

stat Before After
total runs 15 980 32 739
total time 2.0001 s 2.0000 s
average run 125 μs 61 μs
runs/second 8 000.0 16 393
units 100 100
units/second 800 000 1 639 344
time per unit 1.2500 μs 0.6100 μs

CollectionEquatable (dynamic, small)

stat Before After
total runs 251 623 223 689
total time 2.0000 s 2.0000 s
average run 7 μs 8 μs
runs/second 142 857 125 000
units 100 100
units/second 14 285 714 12 500 000
time per unit 0.0700 μs 0.0800 μs

CollectionEquatable (dynamic, medium)

stat Before After
total runs 251 419 217 705
total time 2.0000 s 2.0000 s
average run 7 μs 9 μs
runs/second 142 857 111 111
units 100 100
units/second 14 285 714 11 111 111
time per unit 0.0700 μs 0.0900 μs

CollectionEquatable (dynamic, large)

stat Before After
total runs 249 609 215 003
total time 2.0000 s 2.0000 s
average run 8 μs 9 μs
runs/second 125 000 111 111
units 100 100
units/second 12 500 000 11 111 111
time per unit 0.0800 μs 0.0900 μs

- extra checks in iterableEquals caused a performance hit in benchmarks
- use propsEquals to compare List<Object?> with no extra checks
@ShakyaCsun ShakyaCsun requested a review from felangel as a code owner April 17, 2025 18:45
@ShakyaCsun
Copy link
Author

  1. the setEquals function can be safely deleted now and replaced with iterableEquals in the tests but looking at the comment on equals function i.e. breaking change: equals removed in v2.0.6 #187, I decided to leave it in for now.
  2. I used propsEquals instead of modifying and using equals to avoid checking for null, but maybe we can remove nullable params from equals instead?
  3. I also noticed we could change mapPropsToHashCode to take List<Object?> instead of Iterable<Object?>? and avoid null checks there as well but wanted to get your thoughts before changing function signatures even though these utils aren't publicly exported.
  4. Even though Equatable objects with Iterable and List with same elements are no longer equal, they still produce the same hashCode. One idea I had was to change
    return hash ^ object.length;
    to
return hash ^ (object is List ? 'List${object.length}'.hashCode : object.length);

but maybe there's a better way

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.

Assertion bug: 'a is! Set && b is! Set': iterableEquals doesn't support Sets

1 participant