huge speedup to cljs version by optimizing field access
This commit is contained in:
parent
71b3f6e462
commit
859b31bce7
3 changed files with 49 additions and 46 deletions
4
src/com/rpl/specter/field_clj.clj
Normal file
4
src/com/rpl/specter/field_clj.clj
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
(ns com.rpl.specter.field-clj)
|
||||||
|
|
||||||
|
(defmacro field [obj field]
|
||||||
|
`(. ~obj ~field))
|
||||||
6
src/com/rpl/specter/field_cljs.clj
Normal file
6
src/com/rpl/specter/field_cljs.clj
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
(ns com.rpl.specter.field-cljs)
|
||||||
|
|
||||||
|
(defmacro field [obj field]
|
||||||
|
(let [getter (symbol (str ".-" field))]
|
||||||
|
`(~getter ~obj)
|
||||||
|
))
|
||||||
|
|
@ -1,23 +1,16 @@
|
||||||
(ns com.rpl.specter.impl
|
(ns com.rpl.specter.impl
|
||||||
|
#?(:cljs (:require-macros
|
||||||
|
[com.rpl.specter.field-cljs :refer [field]]))
|
||||||
(:use [com.rpl.specter.protocols :only
|
(:use [com.rpl.specter.protocols :only
|
||||||
[comp-paths*
|
[comp-paths*
|
||||||
select* transform* collect-val select-full* transform-full*]])
|
select* transform* collect-val select-full* transform-full*]]
|
||||||
|
#?(:clj [com.rpl.specter.field-clj :only [field]]))
|
||||||
(:require [com.rpl.specter.protocols :as p]
|
(:require [com.rpl.specter.protocols :as p]
|
||||||
[clojure.walk :as walk]
|
[clojure.walk :as walk]
|
||||||
[clojure.core.reducers :as r]
|
[clojure.core.reducers :as r]
|
||||||
[clojure.string :as s])
|
[clojure.string :as s])
|
||||||
)
|
)
|
||||||
|
|
||||||
#?(
|
|
||||||
:clj
|
|
||||||
(defmacro field [obj quoted-field]
|
|
||||||
`(. ~obj ~(second quoted-field)))
|
|
||||||
|
|
||||||
:cljs
|
|
||||||
(defn field [obj field]
|
|
||||||
(aget obj (s/replace (str field) "-" "_")))
|
|
||||||
)
|
|
||||||
|
|
||||||
#?(
|
#?(
|
||||||
:clj
|
:clj
|
||||||
(do
|
(do
|
||||||
|
|
@ -231,16 +224,16 @@
|
||||||
|
|
||||||
|
|
||||||
(defn extype [^TransformFunctions f]
|
(defn extype [^TransformFunctions f]
|
||||||
(let [^ExecutorFunctions exs (field f 'executors)]
|
(let [^ExecutorFunctions exs (field f executors)]
|
||||||
(field exs 'type)
|
(field exs type)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defn- combine-same-types [[^TransformFunctions f & _ :as all]]
|
(defn- combine-same-types [[^TransformFunctions f & _ :as all]]
|
||||||
(if (empty? all)
|
(if (empty? all)
|
||||||
(coerce-path nil)
|
(coerce-path nil)
|
||||||
(let [^ExecutorFunctions exs (field f 'executors)
|
(let [^ExecutorFunctions exs (field f executors)
|
||||||
|
|
||||||
t (field exs 'type)
|
t (field exs type)
|
||||||
|
|
||||||
combiner
|
combiner
|
||||||
(if (= t :svalspath)
|
(if (= t :svalspath)
|
||||||
|
|
@ -258,16 +251,16 @@
|
||||||
(reduce (fn [^TransformFunctions curr ^TransformFunctions next]
|
(reduce (fn [^TransformFunctions curr ^TransformFunctions next]
|
||||||
(->TransformFunctions
|
(->TransformFunctions
|
||||||
exs
|
exs
|
||||||
(combiner (field curr 'selector) (field next 'selector))
|
(combiner (field curr selector) (field next selector))
|
||||||
(combiner (field curr 'transformer) (field next 'transformer))
|
(combiner (field curr transformer) (field next transformer))
|
||||||
))
|
))
|
||||||
all))))
|
all))))
|
||||||
|
|
||||||
(defn coerce-structure-vals [^TransformFunctions tfns]
|
(defn coerce-structure-vals [^TransformFunctions tfns]
|
||||||
(if (= (extype tfns) :svalspath)
|
(if (= (extype tfns) :svalspath)
|
||||||
tfns
|
tfns
|
||||||
(let [selector (field tfns 'selector)
|
(let [selector (field tfns selector)
|
||||||
transformer (field tfns 'transformer)]
|
transformer (field tfns transformer)]
|
||||||
(->TransformFunctions
|
(->TransformFunctions
|
||||||
StructureValsPathExecutor
|
StructureValsPathExecutor
|
||||||
(fn [vals structure next-fn]
|
(fn [vals structure next-fn]
|
||||||
|
|
@ -333,7 +326,7 @@
|
||||||
(set_cell cell val))
|
(set_cell cell val))
|
||||||
|
|
||||||
(defn get-cell [cell]
|
(defn get-cell [cell]
|
||||||
#?(:clj (get_cell cell) :cljs (field cell 'q))
|
#?(:clj (get_cell cell) :cljs (field cell q))
|
||||||
)
|
)
|
||||||
|
|
||||||
(defn update-cell! [cell afn]
|
(defn update-cell! [cell afn]
|
||||||
|
|
@ -392,14 +385,14 @@
|
||||||
|
|
||||||
(defn compiled-select*
|
(defn compiled-select*
|
||||||
[^com.rpl.specter.impl.TransformFunctions tfns structure]
|
[^com.rpl.specter.impl.TransformFunctions tfns structure]
|
||||||
(let [^com.rpl.specter.impl.ExecutorFunctions ex (field tfns 'executors)]
|
(let [^com.rpl.specter.impl.ExecutorFunctions ex (field tfns executors)]
|
||||||
((field ex 'select-executor) (field tfns 'selector) structure)
|
((field ex select-executor) (field tfns selector) structure)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defn compiled-transform*
|
(defn compiled-transform*
|
||||||
[^com.rpl.specter.impl.TransformFunctions tfns transform-fn structure]
|
[^com.rpl.specter.impl.TransformFunctions tfns transform-fn structure]
|
||||||
(let [^com.rpl.specter.impl.ExecutorFunctions ex (field tfns 'executors)]
|
(let [^com.rpl.specter.impl.ExecutorFunctions ex (field tfns executors)]
|
||||||
((field ex 'transform-executor) (field tfns 'transformer) transform-fn structure)
|
((field ex transform-executor) (field tfns transformer) transform-fn structure)
|
||||||
))
|
))
|
||||||
|
|
||||||
(defn selected?*
|
(defn selected?*
|
||||||
|
|
@ -468,29 +461,29 @@
|
||||||
PosStructurePath
|
PosStructurePath
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(if-not (empty? structure)
|
(if-not (empty? structure)
|
||||||
(next-fn ((field this 'getter) structure))))
|
(next-fn ((field this getter) structure))))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
(if (empty? structure)
|
(if (empty? structure)
|
||||||
structure
|
structure
|
||||||
((field this 'setter) structure (next-fn ((field this 'getter) structure))))))
|
((field this setter) structure (next-fn ((field this getter) structure))))))
|
||||||
|
|
||||||
(deftype WalkerStructurePath [afn])
|
(deftype WalkerStructurePath [afn])
|
||||||
|
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/StructurePath
|
||||||
WalkerStructurePath
|
WalkerStructurePath
|
||||||
(select* [^WalkerStructurePath this structure next-fn]
|
(select* [^WalkerStructurePath this structure next-fn]
|
||||||
(walk-select (field this 'afn) next-fn structure))
|
(walk-select (field this afn) next-fn structure))
|
||||||
(transform* [^WalkerStructurePath this structure next-fn]
|
(transform* [^WalkerStructurePath this structure next-fn]
|
||||||
(walk-until (field this 'afn) next-fn structure)))
|
(walk-until (field this afn) next-fn structure)))
|
||||||
|
|
||||||
(deftype CodeWalkerStructurePath [afn])
|
(deftype CodeWalkerStructurePath [afn])
|
||||||
|
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/StructurePath
|
||||||
CodeWalkerStructurePath
|
CodeWalkerStructurePath
|
||||||
(select* [^CodeWalkerStructurePath this structure next-fn]
|
(select* [^CodeWalkerStructurePath this structure next-fn]
|
||||||
(walk-select (field this 'afn) next-fn structure))
|
(walk-select (field this afn) next-fn structure))
|
||||||
(transform* [^CodeWalkerStructurePath this structure next-fn]
|
(transform* [^CodeWalkerStructurePath this structure next-fn]
|
||||||
(codewalk-until (field this 'afn) next-fn structure)))
|
(codewalk-until (field this afn) next-fn structure)))
|
||||||
|
|
||||||
|
|
||||||
(deftype FilterStructurePath [path])
|
(deftype FilterStructurePath [path])
|
||||||
|
|
@ -498,9 +491,9 @@
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/StructurePath
|
||||||
FilterStructurePath
|
FilterStructurePath
|
||||||
(select* [^FilterStructurePath this structure next-fn]
|
(select* [^FilterStructurePath this structure next-fn]
|
||||||
(->> structure (filter #(selected?* (field this 'path) %)) doall next-fn))
|
(->> structure (filter #(selected?* (field this path) %)) doall next-fn))
|
||||||
(transform* [^FilterStructurePath this structure next-fn]
|
(transform* [^FilterStructurePath this structure next-fn]
|
||||||
(let [[filtered ancestry] (filter+ancestry (field this 'path) structure)
|
(let [[filtered ancestry] (filter+ancestry (field this path) structure)
|
||||||
;; the vec is necessary so that we can get by index later
|
;; the vec is necessary so that we can get by index later
|
||||||
;; (can't get by index for cons'd lists)
|
;; (can't get by index for cons'd lists)
|
||||||
next (vec (next-fn filtered))]
|
next (vec (next-fn filtered))]
|
||||||
|
|
@ -514,9 +507,9 @@
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/StructurePath
|
||||||
KeyPath
|
KeyPath
|
||||||
(select* [^KeyPath this structure next-fn]
|
(select* [^KeyPath this structure next-fn]
|
||||||
(key-select (field this 'akey) structure next-fn))
|
(key-select (field this akey) structure next-fn))
|
||||||
(transform* [^KeyPath this structure next-fn]
|
(transform* [^KeyPath this structure next-fn]
|
||||||
(key-transform (field this 'akey) structure next-fn)
|
(key-transform (field this akey) structure next-fn)
|
||||||
))
|
))
|
||||||
|
|
||||||
(deftype SelectCollector [sel-fn selector])
|
(deftype SelectCollector [sel-fn selector])
|
||||||
|
|
@ -524,20 +517,20 @@
|
||||||
(extend-protocol p/Collector
|
(extend-protocol p/Collector
|
||||||
SelectCollector
|
SelectCollector
|
||||||
(collect-val [^SelectCollector this structure]
|
(collect-val [^SelectCollector this structure]
|
||||||
((field this 'sel-fn) (field this 'selector) structure)))
|
((field this sel-fn) (field this selector) structure)))
|
||||||
|
|
||||||
(deftype SRangePath [start-fn end-fn])
|
(deftype SRangePath [start-fn end-fn])
|
||||||
|
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/StructurePath
|
||||||
SRangePath
|
SRangePath
|
||||||
(select* [^SRangePath this structure next-fn]
|
(select* [^SRangePath this structure next-fn]
|
||||||
(let [start ((field this 'start-fn) structure)
|
(let [start ((field this start-fn) structure)
|
||||||
end ((field this 'end-fn) structure)]
|
end ((field this end-fn) structure)]
|
||||||
(next-fn (-> structure vec (subvec start end)))
|
(next-fn (-> structure vec (subvec start end)))
|
||||||
))
|
))
|
||||||
(transform* [^SRangePath this structure next-fn]
|
(transform* [^SRangePath this structure next-fn]
|
||||||
(let [start ((field this 'start-fn) structure)
|
(let [start ((field this start-fn) structure)
|
||||||
end ((field this 'end-fn) structure)
|
end ((field this end-fn) structure)
|
||||||
structurev (vec structure)
|
structurev (vec structure)
|
||||||
newpart (next-fn (-> structurev (subvec start end)))
|
newpart (next-fn (-> structurev (subvec start end)))
|
||||||
res (concat (subvec structurev 0 start)
|
res (concat (subvec structurev 0 start)
|
||||||
|
|
@ -553,9 +546,9 @@
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/StructurePath
|
||||||
ViewPath
|
ViewPath
|
||||||
(select* [^ViewPath this structure next-fn]
|
(select* [^ViewPath this structure next-fn]
|
||||||
(->> structure ((field this 'view-fn)) next-fn))
|
(->> structure ((field this view-fn)) next-fn))
|
||||||
(transform* [^ViewPath this structure next-fn]
|
(transform* [^ViewPath this structure next-fn]
|
||||||
(->> structure ((field this 'view-fn)) next-fn)
|
(->> structure ((field this view-fn)) next-fn)
|
||||||
))
|
))
|
||||||
|
|
||||||
(deftype PutValCollector [val])
|
(deftype PutValCollector [val])
|
||||||
|
|
@ -563,7 +556,7 @@
|
||||||
(extend-protocol p/Collector
|
(extend-protocol p/Collector
|
||||||
PutValCollector
|
PutValCollector
|
||||||
(collect-val [^PutValCollector this structure]
|
(collect-val [^PutValCollector this structure]
|
||||||
(field this 'val)
|
(field this val)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -592,12 +585,12 @@
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/StructurePath
|
||||||
ConditionalPath
|
ConditionalPath
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(if-let [selector (retrieve-selector (field this 'cond-pairs) structure)]
|
(if-let [selector (retrieve-selector (field this cond-pairs) structure)]
|
||||||
(->> (compiled-select* selector structure)
|
(->> (compiled-select* selector structure)
|
||||||
(mapcat next-fn)
|
(mapcat next-fn)
|
||||||
doall)))
|
doall)))
|
||||||
(transform* [this structure next-fn]
|
(transform* [this structure next-fn]
|
||||||
(if-let [selector (retrieve-selector (field this 'cond-pairs) structure)]
|
(if-let [selector (retrieve-selector (field this cond-pairs) structure)]
|
||||||
(compiled-transform* selector next-fn structure)
|
(compiled-transform* selector next-fn structure)
|
||||||
structure
|
structure
|
||||||
)))
|
)))
|
||||||
|
|
@ -607,7 +600,7 @@
|
||||||
(extend-protocol p/StructurePath
|
(extend-protocol p/StructurePath
|
||||||
MultiPath
|
MultiPath
|
||||||
(select* [this structure next-fn]
|
(select* [this structure next-fn]
|
||||||
(->> (field this 'paths)
|
(->> (field this paths)
|
||||||
(mapcat #(compiled-select* % structure))
|
(mapcat #(compiled-select* % structure))
|
||||||
(mapcat next-fn)
|
(mapcat next-fn)
|
||||||
doall
|
doall
|
||||||
|
|
@ -617,7 +610,7 @@
|
||||||
(fn [structure selector]
|
(fn [structure selector]
|
||||||
(compiled-transform* selector next-fn structure))
|
(compiled-transform* selector next-fn structure))
|
||||||
structure
|
structure
|
||||||
(field this 'paths))
|
(field this paths))
|
||||||
))
|
))
|
||||||
|
|
||||||
(defn filter-select [afn structure next-fn]
|
(defn filter-select [afn structure next-fn]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue