Use transients for better caching performance

This commit is contained in:
Dan Holmsand 2015-10-02 10:18:48 +02:00
parent 6aa26253d8
commit eb83776b3d
1 changed files with 38 additions and 27 deletions

View File

@ -5,7 +5,6 @@
[reagent.debug :refer-macros [dbg log warn error dev?]])) [reagent.debug :refer-macros [dbg log warn error dev?]]))
(declare ^:dynamic *ratom-context*) (declare ^:dynamic *ratom-context*)
(defonce cached-reactions {})
(defonce ^boolean debug false) (defonce ^boolean debug false)
(defonce ^boolean silent false) (defonce ^boolean silent false)
(defonce generation 0) (defonce generation 0)
@ -18,8 +17,7 @@
;;; Utilities ;;; Utilities
(defn running [] (defn running []
(+ @-running (+ @-running))
(count cached-reactions)))
(defn capture-derefed [f obj] (defn capture-derefed [f obj]
(set! (.-cljsCaptured obj) nil) (set! (.-cljsCaptured obj) nil)
@ -177,34 +175,47 @@
(declare make-reaction) (declare make-reaction)
(defn- cached-reaction [f key obj destroy] (defonce cached-reactions (transient {}))
(if-some [r (get cached-reactions key)]
(defn- cached-reaction [f k1 k2 obj destroy]
(let [m (if-some [v (get cached-reactions k1)]
v
(let [newm (transient {})]
(assoc! cached-reactions k1 newm)
newm))]
(if-some [r (get m k2)]
(-deref r) (-deref r)
(if-not (nil? *ratom-context*) (if-not (nil? *ratom-context*)
(let [r (make-reaction (let [r (make-reaction
f :on-dispose (fn [x] f :on-dispose (fn [x]
(set! cached-reactions (when debug (swap! -running dec))
(dissoc cached-reactions key)) (let [m (get cached-reactions k1)]
(->> (dissoc! m k2)
(assoc! cached-reactions k1)
(set! cached-reactions)))
(when-not (nil? obj) (when-not (nil? obj)
(set! (.-reaction obj) nil)) (set! (.-reaction obj) nil))
(when-not (nil? destroy) (when-not (nil? destroy)
(destroy x)) (destroy x))
nil)) nil))
v (-deref r)] v (-deref r)]
(set! cached-reactions (assoc cached-reactions key r)) (->> (assoc! m k2 r)
(assoc! cached-reactions k1)
(set! cached-reactions))
(when debug (swap! -running inc))
(when-not (nil? obj) (when-not (nil? obj)
(set! (.-reaction obj) r)) (set! (.-reaction obj) r))
v) v)
(f)))) (f)))))
(deftype Track [f key ^:mutable reaction] (deftype Track [f args ^:mutable reaction]
IReactiveAtom IReactiveAtom
IDeref IDeref
(-deref [this] (-deref [this]
(if-some [r reaction] (if-some [r reaction]
(-deref r) (-deref r)
(cached-reaction f key this nil))) (cached-reaction #(apply f args) f args this nil)))
IEquiv IEquiv
(-equiv [_ other] (-equiv [_ other]
@ -218,7 +229,7 @@
(-pr-writer [a w opts] (pr-atom a w opts "Track:"))) (-pr-writer [a w opts] (pr-atom a w opts "Track:")))
(defn make-track [f args] (defn make-track [f args]
(Track. #(apply f args) [f args] nil)) (Track. f args nil))
(defn make-track! [f args] (defn make-track! [f args]
(let [t (make-track f args) (let [t (make-track f args)
@ -267,7 +278,7 @@
(let [f (if (satisfies? IDeref ratom) (let [f (if (satisfies? IDeref ratom)
#(get-in @ratom path) #(get-in @ratom path)
#(ratom path))] #(ratom path))]
(cached-reaction f [::cursor ratom path] this nil)))] (cached-reaction f ratom path this nil)))]
(._set-state this oldstate newstate) (._set-state this oldstate newstate)
newstate)) newstate))
@ -318,7 +329,7 @@
(defn with-let-values [key] (defn with-let-values [key]
(if-some [c *ratom-context*] (if-some [c *ratom-context*]
(cached-reaction array [(reaction-key c) key] (cached-reaction array key (reaction-key c)
nil with-let-destroy) nil with-let-destroy)
(array))) (array)))