aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Viney <richard.viney@gmail.com>2024-11-29 09:53:00 +1300
committerLouis Pilfold <louis@lpil.uk>2024-12-03 13:30:57 +0000
commit2f3b2bbaf925c432f0fc128336c4e62b7c9d34a9 (patch)
treec6d0419298058978512653aa23d1e79bd5b4bfd8
parentc339a9788fc514cad8cbd6b1e9b04b32d9e3e967 (diff)
downloadgleam_stdlib-2f3b2bbaf925c432f0fc128336c4e62b7c9d34a9.tar.gz
gleam_stdlib-2f3b2bbaf925c432f0fc128336c4e62b7c9d34a9.zip
Optimise dict equality check on JavaScript
-rw-r--r--CHANGELOG.md5
-rw-r--r--src/dict.mjs24
-rw-r--r--test/gleam/dict_test.gleam8
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() {