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

View file

@ -95,6 +95,18 @@
(updater this structure next-fn)) (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] (defn obj-extends? [prot obj]
(->> obj (find-protocol-impl prot) nil? not)) (->> obj (find-protocol-impl prot) nil? not))
@ -149,11 +161,8 @@
all))) all)))
(defn coerce-structure-vals [^TransformFunctions tfns] (defn coerce-structure-vals [^TransformFunctions tfns]
(condp = (extype tfns) (if (= (extype tfns) :svalspath)
:svalspath
tfns tfns
:spath
(let [selector (.selector tfns) (let [selector (.selector tfns)
updater (.updater tfns)] updater (.updater tfns)]
(->TransformFunctions (->TransformFunctions
@ -182,6 +191,24 @@
combine-same-types) 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 ;; cell implementation idea taken from prismatic schema library
(definterface PMutableCell (definterface PMutableCell
(get_cell ^Object []) (get_cell ^Object [])