diff options
author | Richard Viney <richard.viney@gmail.com> | 2024-11-29 09:53:00 +1300 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2024-12-03 13:30:57 +0000 |
commit | 2f3b2bbaf925c432f0fc128336c4e62b7c9d34a9 (patch) | |
tree | c6d0419298058978512653aa23d1e79bd5b4bfd8 | |
parent | c339a9788fc514cad8cbd6b1e9b04b32d9e3e967 (diff) | |
download | gleam_stdlib-2f3b2bbaf925c432f0fc128336c4e62b7c9d34a9.tar.gz gleam_stdlib-2f3b2bbaf925c432f0fc128336c4e62b7c9d34a9.zip |
Optimise dict equality check on JavaScript
-rw-r--r-- | CHANGELOG.md | 5 | ||||
-rw-r--r-- | src/dict.mjs | 24 | ||||
-rw-r--r-- | test/gleam/dict_test.gleam | 8 |
3 files changed, 32 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 88c9509..5f36579 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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` diff --git a/src/dict.mjs b/src/dict.mjs index 950037e..472d63d 100644 --- a/src/dict.mjs +++ b/src/dict.mjs @@ -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(); diff --git a/test/gleam/dict_test.gleam b/test/gleam/dict_test.gleam index 5937e14..d9b8822 100644 --- a/test/gleam/dict_test.gleam +++ b/test/gleam/dict_test.gleam @@ -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() { |