Skip to content

Commit

Permalink
Optimise dict equality check on JavaScript
Browse files Browse the repository at this point in the history
  • Loading branch information
richard-viney authored and lpil committed Dec 3, 2024
1 parent c339a97 commit 2f3b2bb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Unreleased

- Comparing two `Dict`s of equal size has been optimised on the JavaScript
target.

## v0.45.0 - 2024-11-28

- The performance of `string.trim`, `string.trim_start`, and `string.trim_end`
Expand Down
24 changes: 19 additions & 5 deletions src/dict.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -968,10 +968,24 @@ export default class Dict {
if (!(o instanceof Dict) || this.size !== o.size) {
return false;
}
let equal = true;
this.forEach((v, k) => {
equal = equal && isEqual(o.get(k, !v), v);
});
return equal;

try {
this.forEach((v, k) => {
if (!isEqual(o.get(k, !v), v)) {
throw unequalDictSymbol;
}
});
return true;
} catch (e) {
if (e === unequalDictSymbol) {
return false;
}

throw e;
}
}
}

// This is thrown internally in Dict.equals() so that it returns false as soon
// as a non-matching key is found
const unequalDictSymbol = Symbol();
8 changes: 8 additions & 0 deletions test/gleam/dict_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ pub fn from_list_test() {
[#(1, 0), #(1, 1)]
|> dict.from_list
|> should.equal(dict.from_list([#(1, 1)]))

[#(1, 0), #(2, 1)]
|> dict.from_list
|> should.not_equal(dict.from_list([#(1, 0), #(2, 2)]))

[#(1, 0), #(2, 1)]
|> dict.from_list
|> should.not_equal(dict.from_list([#(1, 0), #(3, 1)]))
}

pub fn has_key_test() {
Expand Down

0 comments on commit 2f3b2bb

Please sign in to comment.