major performnace enhancements for ALL on vectors (2x) and maps (10% for arraymas, 25% for hashmaps)
This commit is contained in:
parent
0bc26c950e
commit
86f05b3cbe
2 changed files with 72 additions and 24 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
## 0.11.1 (unreleased)
|
## 0.11.1 (unreleased)
|
||||||
* More efficient inline caching for Clojure version, now inline caching is always within 5% of manually precompiled code
|
* More efficient inline caching for Clojure version, now inline caching is always within 5% of manually precompiled code
|
||||||
* Significant performance improvement for ALL transform on maps for Clojure version (25% on simple benchmarks)
|
* Huge performance improvement for ALL transform on maps and vectors
|
||||||
* Significant performance improvements for FIRST/LAST for vectors
|
* Significant performance improvements for FIRST/LAST for vectors
|
||||||
* Huge performance improvements for `if-path` and `cond-path`
|
* Huge performance improvements for `if-path` and `cond-path`
|
||||||
* Eliminated compiler warnings for ClojureScript version
|
* Eliminated compiler warnings for ClojureScript version
|
||||||
|
|
|
||||||
|
|
@ -593,36 +593,84 @@
|
||||||
(defn queue? [coll]
|
(defn queue? [coll]
|
||||||
(instance? clojure.lang.PersistentQueue coll))
|
(instance? clojure.lang.PersistentQueue coll))
|
||||||
|
|
||||||
#+clj
|
(defprotocol AllTransformProtocol
|
||||||
(defn all-transform [structure next-fn]
|
(all-transform [structure next-fn]))
|
||||||
(let [empty-structure (empty structure)]
|
|
||||||
(cond (and (list? empty-structure) (not (queue? empty-structure)))
|
|
||||||
;; this is done to maintain order, otherwise lists get reversed
|
|
||||||
(doall (map next-fn structure))
|
|
||||||
|
|
||||||
(map? structure)
|
(defn- non-transient-map-all-transform [structure next-fn empty-map]
|
||||||
;; reduce-kv is much faster than doing r/map through call to (into ...)
|
(reduce-kv
|
||||||
(reduce-kv
|
(fn [m k v]
|
||||||
(fn [m k v]
|
(let [[newk newv] (next-fn [k v])]
|
||||||
(let [[newk newv] (next-fn [k v])]
|
(assoc m newk newv)
|
||||||
(assoc m newk newv)
|
))
|
||||||
))
|
empty-map
|
||||||
empty-structure
|
structure
|
||||||
structure
|
))
|
||||||
)
|
|
||||||
|
|
||||||
:else
|
(extend-protocol AllTransformProtocol
|
||||||
(->> structure (r/map next-fn) (into empty-structure))
|
#+clj clojure.lang.PersistentVector #+cljs cljs.core/PersistentVector
|
||||||
)))
|
(all-transform [structure next-fn]
|
||||||
|
(mapv next-fn structure))
|
||||||
|
|
||||||
#+cljs
|
#+clj clojure.lang.PersistentArrayMap #+cljs cljs.core/PersistentArrayMap
|
||||||
(defn all-transform [structure next-fn]
|
(all-transform [structure next-fn]
|
||||||
(let [empty-structure (empty structure)]
|
(non-transient-map-all-transform structure next-fn {})
|
||||||
(if (and (list? empty-structure) (not (queue? empty-structure)))
|
)
|
||||||
|
|
||||||
|
#+clj clojure.lang.PersistentTreeMap #+cljs cljs.core/PersistentTreeMap
|
||||||
|
(all-transform [structure next-fn]
|
||||||
|
(non-transient-map-all-transform structure next-fn (sorted-map))
|
||||||
|
)
|
||||||
|
|
||||||
|
#+clj clojure.lang.PersistentHashMap #+cljs cljs.core/PersistentHashMap
|
||||||
|
(all-transform [structure next-fn]
|
||||||
|
(persistent!
|
||||||
|
(reduce-kv
|
||||||
|
(fn [m k v]
|
||||||
|
(let [[newk newv] (next-fn [k v])]
|
||||||
|
(assoc! m newk newv)
|
||||||
|
))
|
||||||
|
(transient
|
||||||
|
#+clj clojure.lang.PersistentHashMap/EMPTY #+cljs cljs.core.PersistentHashMap.EMPTY
|
||||||
|
)
|
||||||
|
structure
|
||||||
|
)))
|
||||||
|
|
||||||
|
|
||||||
|
#+clj
|
||||||
|
Object
|
||||||
|
#+clj
|
||||||
|
(all-transform [structure next-fn]
|
||||||
|
(let [empty-structure (empty structure)]
|
||||||
|
(cond (and (list? empty-structure) (not (queue? empty-structure)))
|
||||||
|
;; this is done to maintain order, otherwise lists get reversed
|
||||||
|
(doall (map next-fn structure))
|
||||||
|
|
||||||
|
(map? structure)
|
||||||
|
;; reduce-kv is much faster than doing r/map through call to (into ...)
|
||||||
|
(reduce-kv
|
||||||
|
(fn [m k v]
|
||||||
|
(let [[newk newv] (next-fn [k v])]
|
||||||
|
(assoc m newk newv)
|
||||||
|
))
|
||||||
|
empty-structure
|
||||||
|
structure
|
||||||
|
)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(->> structure (r/map next-fn) (into empty-structure))
|
||||||
|
)))
|
||||||
|
|
||||||
|
#+cljs
|
||||||
|
default
|
||||||
|
#+cljs
|
||||||
|
(all-transform [structure next-fn]
|
||||||
|
(let [empty-structure (empty structure)]
|
||||||
|
(if (and (list? empty-structure) (not (queue? empty-structure)))
|
||||||
;; this is done to maintain order, otherwise lists get reversed
|
;; this is done to maintain order, otherwise lists get reversed
|
||||||
(doall (map next-fn structure))
|
(doall (map next-fn structure))
|
||||||
(into empty-structure (map #(next-fn %)) structure)
|
(into empty-structure (map #(next-fn %)) structure)
|
||||||
)))
|
)))
|
||||||
|
)
|
||||||
|
|
||||||
(deftype AllNavigator [])
|
(deftype AllNavigator [])
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue