speed up non-compiled execution path to where it was before

This commit is contained in:
Nathan Marz 2015-05-11 14:21:02 -04:00
parent cd994b10ee
commit 7f69a99861
2 changed files with 38 additions and 11 deletions

View file

@ -21,7 +21,7 @@
(defn select
"Navigates to and returns a sequence of all the elements specified by the selector."
[selector structure]
(compiled-select (comp-paths* selector)
(compiled-select (comp-unoptimal selector)
structure))
(defn compiled-select-one
@ -36,7 +36,7 @@
(defn select-one
"Like select, but returns either one element or nil. Throws exception if multiple elements found"
[selector structure]
(compiled-select-one (comp-paths* selector) structure))
(compiled-select-one (comp-unoptimal selector) structure))
(defn compiled-select-one!
"Version of select-one! that takes in a selector pre-compiled with comp-paths"
@ -49,7 +49,7 @@
(defn select-one!
"Returns exactly one element, throws exception if zero or multiple elements found"
[selector structure]
(compiled-select-one! (comp-paths* selector) structure))
(compiled-select-one! (comp-unoptimal selector) structure))
(defn compiled-select-first
"Version of select-first that takes in a selector pre-compiled with comp-paths"
@ -59,7 +59,7 @@
(defn select-first
"Returns first element found. Not any more efficient than select, just a convenience"
[selector structure]
(compiled-select-first (comp-paths* selector) structure))
(compiled-select-first (comp-unoptimal selector) structure))
;; Update functions
@ -74,7 +74,7 @@
"Navigates to each value specified by the selector and replaces it by the result of running
the update-fn on it"
[selector update-fn structure]
(compiled-update (comp-paths* selector) update-fn structure))
(compiled-update (comp-unoptimal selector) update-fn structure))
(defn compiled-setval
"Version of setval that takes in a selector pre-compiled with comp-paths"
@ -84,7 +84,7 @@
(defn setval
"Navigates to each value specified by the selector and replaces it by val"
[selector val structure]
(compiled-setval (comp-paths* selector) val structure))
(compiled-setval (comp-unoptimal selector) val structure))
(defn compiled-replace-in
"Version of replace-in that takes in a selector pre-compiled with comp-paths"
@ -112,7 +112,7 @@
in the final return. replace-in is useful for situations where you need to know the specific values
of what was updated in the data structure."
[selector update-fn structure & {:keys [merge-fn] :or {merge-fn concat}}]
(compiled-replace-in (comp-paths* selector) update-fn structure :merge-fn merge-fn))
(compiled-replace-in (comp-unoptimal selector) update-fn structure :merge-fn merge-fn))
;; Built-in pathing and context operations

View file

@ -95,6 +95,18 @@
(updater this structure next-fn))
)))
(defn coerce-structure-path-direct [this]
(let [pimpl (find-protocol-impl! StructurePath this)
selector (:select* pimpl)
updater (:update* pimpl)]
(->TransformFunctions
StructureValsPathExecutor
(fn [vals structure next-fn]
(selector this structure (fn [structure] (next-fn vals structure))))
(fn [vals structure next-fn]
(updater this structure (fn [structure] (next-fn vals structure))))
)))
(defn obj-extends? [prot obj]
(->> obj (find-protocol-impl prot) nil? not))
@ -149,11 +161,8 @@
all)))
(defn coerce-structure-vals [^TransformFunctions tfns]
(condp = (extype tfns)
:svalspath
(if (= (extype tfns) :svalspath)
tfns
:spath
(let [selector (.selector tfns)
updater (.updater tfns)]
(->TransformFunctions
@ -182,6 +191,24 @@
combine-same-types)
))))
(defn coerce-structure-vals-direct [this]
(cond (obj-extends? StructurePath this) (coerce-structure-path-direct this)
(obj-extends? Collector this) (coerce-collector this)
(obj-extends? StructureValsPath this) (coerce-structure-vals-path this)
(instance? TransformFunctions this) this
:else (throw-illegal (no-prot-error-str this))
))
;;this composes paths together much faster than comp-paths* but the resulting composition
;;won't execute as fast. Useful for when select/update are used without pre-compiled paths
;;(where cost of compiling dominates execution time)
(defn comp-unoptimal [sp]
(if (instance? java.util.List sp)
(->> sp
(map (fn [p] (-> p coerce-structure-vals-direct)))
combine-same-types)
(coerce-path sp)))
;; cell implementation idea taken from prismatic schema library
(definterface PMutableCell
(get_cell ^Object [])