Skip to content

Commit

Permalink
CLJS-582: (set [1 2 2]) => #{1 2 2}
Browse files Browse the repository at this point in the history
Remove ill considered set construction optimization - was naively
applying idea from list construction optimization to sets.

Instead handle IndexedSeq case specially as this optimizes hash-set as
well as small PersistentVector case. Otherwise just loop/recur reduce on
a transient set with appropiate type hinting.
  • Loading branch information
swannodette committed Sep 4, 2013
1 parent 50d75eb commit 95d92ba
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 22 deletions.
41 changes: 19 additions & 22 deletions src/cljs/cljs/core.cljs
Expand Up @@ -6148,32 +6148,29 @@ reduces them without incurring seq initialization"
(set! cljs.core.PersistentTreeSet/EMPTY
(PersistentTreeSet. nil cljs.core.PersistentTreeMap/EMPTY 0))

(defn hash-set
([] cljs.core.PersistentHashSet/EMPTY)
([& ^not-native keys]
(if (and (instance? IndexedSeq keys)
(< (alength (.-arr keys)) cljs.core.PersistentArrayMap/HASHMAP_THRESHOLD))
(let [karr (.-arr keys)
klen (alength karr)
alen (* 2 klen)
arr (make-array alen)]
(loop [ki 0]
(if (< ki klen)
(let [ai (* 2 ki)]
(aset arr ai (aget karr ki))
(aset arr (inc ai) nil)
(recur (inc ki)))
(cljs.core.PersistentHashSet/fromArray arr true))))
(loop [in keys
^not-native out (-as-transient cljs.core.PersistentHashSet/EMPTY)]
(if-not (nil? in)
(recur (-next in) (-conj! out (-first in)))
(-persistent! out))))))
(defn set-from-indexed-seq [iseq]
(let [arr (.-arr iseq)
ret (areduce arr i ^not-native res (-as-transient #{})
(-conj! res (aget arr i)))]
(-persistent! ^not-native ret)))

(defn set
"Returns a set of the distinct elements of coll."
[coll]
(apply hash-set coll))
(if-not (nil? coll)
(let [^not-native in (seq coll)]
(if (instance? IndexedSeq in)
(set-from-indexed-seq in)
(loop [in in
^not-native out (-as-transient #{})]
(if-not (nil? in)
(recur (-next in) (-conj! out (-first in)))
(-persistent! out)))))
#{}))

(defn hash-set
([] #{})
([& keys] (set keys)))

(defn sorted-set
"Returns a new sorted set with supplied keys."
Expand Down
5 changes: 5 additions & 0 deletions test/cljs/cljs/core_test.cljs
Expand Up @@ -1933,5 +1933,10 @@
(max (f! 5) (g! 10))
(min (f! 5) (g! 10))))))

;; CLJS-582
(assert (= #{1 2} (set [1 2 2])))
(assert (= #{1 2} (hash-set 1 2 2)))
(assert (= #{1 2} (apply hash-set [1 2 2])))

:ok
)

0 comments on commit 95d92ba

Please sign in to comment.