minor performance optimizations to FIRST/LAST

This commit is contained in:
Nathan Marz 2016-06-01 12:02:41 -04:00
parent 6b7d18d874
commit 1c21be2262
2 changed files with 40 additions and 20 deletions

View file

@ -155,9 +155,9 @@
(def VAL (i/->ValCollect)) (def VAL (i/->ValCollect))
(def LAST (comp-paths (i/->PosNavigator last i/set-last))) (def LAST (comp-paths (i/->PosNavigator i/get-last i/update-last)))
(def FIRST (comp-paths (i/->PosNavigator first i/set-first))) (def FIRST (comp-paths (i/->PosNavigator i/get-first i/update-first)))
(defnav (defnav
^{:doc "Uses start-fn and end-fn to determine the bounds of the subsequence ^{:doc "Uses start-fn and end-fn to determine the bounds of the subsequence

View file

@ -439,27 +439,47 @@
(defn- append [coll elem] (defn- append [coll elem]
(-> coll vec (conj elem))) (-> coll vec (conj elem)))
(defprotocol SetExtremes (defprotocol UpdateExtremes
(set-first [s val]) (update-first [s afn])
(set-last [s val])) (update-last [s afn]))
(defn- set-first-list [l v] (defprotocol GetExtremes
(cons v (rest l))) (get-first [s])
(get-last [s]))
(defn- set-last-list [l v] (defn- update-first-list [l afn]
(append (butlast l) v)) (cons (afn (first l)) (rest l)))
(extend-protocol SetExtremes (defn- update-last-list [l afn]
(append (butlast l) (afn (last l))))
(extend-protocol UpdateExtremes
#+clj clojure.lang.PersistentVector #+cljs cljs.core/PersistentVector #+clj clojure.lang.PersistentVector #+cljs cljs.core/PersistentVector
(set-first [v val] (update-first [v afn]
(assoc v 0 val)) (let [val (get v 0)]
(set-last [v val] (assoc v 0 (afn val))
(assoc v (-> v count dec) val)) ))
(update-last [v afn]
(conj (pop v) (afn (peek v)))
)
#+clj Object #+cljs default #+clj Object #+cljs default
(set-first [l val] (update-first [l val]
(set-first-list l val)) (update-first-list l val))
(set-last [l val] (update-last [l val]
(set-last-list l val) (update-last-list l val)
))
(extend-protocol GetExtremes
#+clj clojure.lang.PersistentVector #+cljs cljs.core/PersistentVector
(get-first [v]
(get v 0))
(get-last [v]
(peek v))
#+clj Object #+cljs default
(get-first [s]
(first s))
(get-last [s]
(last s)
)) ))
(defn walk-until [pred on-match-fn structure] (defn walk-until [pred on-match-fn structure]
@ -592,7 +612,7 @@
(collect-val [this structure] (collect-val [this structure]
structure)) structure))
(deftype PosNavigator [getter setter]) (deftype PosNavigator [getter updater])
(extend-protocol p/Navigator (extend-protocol p/Navigator
PosNavigator PosNavigator
@ -602,7 +622,7 @@
(transform* [this structure next-fn] (transform* [this structure next-fn]
(if (empty? structure) (if (empty? structure)
structure structure
((.-setter this) structure (next-fn ((.-getter this) structure)))))) ((.-updater this) structure next-fn))))
(defn srange-select [structure start end next-fn] (defn srange-select [structure start end next-fn]
(next-fn (-> structure vec (subvec start end)))) (next-fn (-> structure vec (subvec start end))))