Permalink
Browse files

CLJS-582: (set [1 2 2]) => #{1 2 2}

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...
1 parent 50d75eb commit 95d92ba4d74a3981b0da94ae4d61adfd6df40b61 @swannodette swannodette committed Sep 4, 2013
Showing with 24 additions and 22 deletions.
  1. +19 −22 src/cljs/cljs/core.cljs
  2. +5 −0 test/cljs/cljs/core_test.cljs
View
41 src/cljs/cljs/core.cljs
@@ -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."
View
5 test/cljs/cljs/core_test.cljs
@@ -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.