From ba268a1eae38e0eb474675c2c5b626a45514babb Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 19 Oct 2025 10:56:01 -0400 Subject: [PATCH 1/4] ObjMap, return original map if new kv is identical --- src/main/cljs/cljs/core.cljs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index 3515da790..c86d105b6 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -12603,15 +12603,19 @@ reduces them without incurring seq initialization" (let [k (if-not (keyword? k) k (keyword->obj-map-key k))] (if (string? k) (if-not (nil? (scan-array 1 k strkeys)) - (let [new-strobj (obj-clone strobj strkeys)] - (gobject/set new-strobj k v) - (ObjMap. meta strkeys new-strobj nil)) ;overwrite - (let [new-strobj (obj-clone strobj strkeys) ; append + (if (identical? v (gobject/get strobj k)) + coll + ;; overwrite + (let [new-strobj (obj-clone strobj strkeys)] + (gobject/set new-strobj k v) + (ObjMap. meta strkeys new-strobj nil))) + ;; append + (let [new-strobj (obj-clone strobj strkeys) new-keys (aclone strkeys)] (gobject/set new-strobj k v) (.push new-keys k) (ObjMap. meta new-keys new-strobj nil))) - ; non-string key. game over. + ;; non-string key. game over. (-with-meta (-kv-reduce coll (fn [ret k v] From 6b453ef5e5210bc298605dc4f18ccdaf23cc16ec Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 19 Oct 2025 11:05:47 -0400 Subject: [PATCH 2/4] same treatment for HashMap and Set --- src/main/cljs/cljs/core.cljs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index c86d105b6..a1edf1242 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -12816,10 +12816,12 @@ reduces them without incurring seq initialization" i (scan-array-equiv 2 k new-bucket)] (aset new-hashobj h new-bucket) (if (some? i) - (do - ; found key, replace - (aset new-bucket (inc i) v) - (HashMap. meta count new-hashobj nil)) + (if (identical? v (aget new-bucket (inc i))) + coll + (do + ; found key, replace + (aset new-bucket (inc i) v) + (HashMap. meta count new-hashobj nil))) (do ; did not find key, append (.push new-bucket k v) @@ -12958,7 +12960,10 @@ reduces them without incurring seq initialization" ICollection (-conj [coll o] - (Set. meta (assoc hash-map o o) nil)) + (let [new-hash-map (assoc hash-map o o)] + (if (identical? new-hash-map hash-map) + coll + (Set. meta new-hash-map nil)))) IEmptyableCollection (-empty [coll] (with-meta (. Set -EMPTY) meta)) From 38f93afcbaf9245db7c2260a0a843266a28315ee Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 19 Oct 2025 11:07:22 -0400 Subject: [PATCH 3/4] tweak --- src/main/cljs/cljs/core.cljs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index a1edf1242..3beaa425c 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -12605,17 +12605,17 @@ reduces them without incurring seq initialization" (if-not (nil? (scan-array 1 k strkeys)) (if (identical? v (gobject/get strobj k)) coll - ;; overwrite + ; overwrite (let [new-strobj (obj-clone strobj strkeys)] (gobject/set new-strobj k v) (ObjMap. meta strkeys new-strobj nil))) - ;; append + ; append (let [new-strobj (obj-clone strobj strkeys) new-keys (aclone strkeys)] (gobject/set new-strobj k v) (.push new-keys k) (ObjMap. meta new-keys new-strobj nil))) - ;; non-string key. game over. + ; non-string key. game over. (-with-meta (-kv-reduce coll (fn [ret k v] From df4a48b71faf6466e752df2aeea6d9bf8c64e2af Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sun, 19 Oct 2025 11:21:27 -0400 Subject: [PATCH 4/4] add some unit tests --- src/test/cljs/cljs/lite_collections_test.cljs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/cljs/cljs/lite_collections_test.cljs b/src/test/cljs/cljs/lite_collections_test.cljs index 16d0296c1..a96148f00 100644 --- a/src/test/cljs/cljs/lite_collections_test.cljs +++ b/src/test/cljs/cljs/lite_collections_test.cljs @@ -28,6 +28,14 @@ (= 1 (aget (clj->js (obj-map :x 1)) "x")) (= 1 (aget (clj->js {:x 1}) "x"))) +(deftest test-unchanged-identical? + (let [m (obj-map :foo 1)] + (identical? m (assoc m :foo 1))) + (let [m (simple-hash-map :foo 1)] + (identical? m (assoc m :foo 1))) + (let [s (simple-set [:foo])] + (identical? s (conj s :foo)))) + (comment (require '[cljs.lite-collections-test] :reload)