Some performance tweaking

This commit is contained in:
Dan Holmsand 2015-09-10 18:30:00 +02:00
parent c6ca75ff0e
commit 80a3c27fac
2 changed files with 36 additions and 32 deletions

View File

@ -199,51 +199,53 @@
(def maybe-dirty 1) (def maybe-dirty 1)
(def is-dirty 2) (def is-dirty 2)
(declare reaction?) (declare Reaction)
(defn- ^boolean reaction? [ra]
(instance? Reaction ra))
(defn- ra-notify-watches [ra oldval newval] (defn- ra-notify-watches [ra oldval newval]
(reduce-kv (fn [_ key f] (reduce-kv (fn [_ key f]
(f key ra oldval newval) (f key ra oldval newval)
nil) nil)
nil ra.watches)) nil (.-watches ra)))
(defn- ra-check-clean [ra] (defn- ra-check-clean [ra]
(when (== ra.dirty? maybe-dirty) (when (== (.-dirty? ra) maybe-dirty)
(set! ra.norun? true) (set! (.-norun? ra) true)
(doseq [w ra.watching] (doseq [w (.-watching ra)]
(when (and (reaction? w) (when (and (reaction? w)
(not (== (.-dirty? w) clean))) (not (== (.-dirty? w) clean)))
(ra-check-clean w) (ra-check-clean w)
(when-not (== (.-dirty? w) clean) (when-not (== (.-dirty? w) clean)
(run w)))) (run w))))
(set! ra.norun? false) (set! (.-norun? ra) false)
(when (== ra.dirty? maybe-dirty) (when (== (.-dirty? ra) maybe-dirty)
(set! ra.dirty? clean)))) (set! (.-dirty? ra) clean))))
(defn- ra-handle-change [ra sender oldval newval] (defn- ra-handle-change [ra sender oldval newval]
(when ra.active? (when ^boolean (.-active? ra)
(let [old-dirty ra.dirty?] (let [old-dirty (.-dirty? ra)]
(set! ra.dirty? (max ra.dirty? (set! (.-dirty? ra) (max (.-dirty? ra)
(if (identical? oldval newval) (if (identical? oldval newval)
(if (reaction? sender) (if (reaction? sender)
maybe-dirty clean) maybe-dirty clean)
is-dirty))) is-dirty)))
(if (and ra.auto-run (not ra.norun?)) (if (and (some? (.-auto-run ra)) (not ^boolean (.-norun? ra)))
(do (do
(ra-check-clean ra) (ra-check-clean ra)
(when-not (== ra.dirty? clean) (when-not (== (.-dirty? ra) clean)
((or ra.auto-run run) ra))) ((or (.-auto-run ra) run) ra)))
(when (== old-dirty clean) (when (== old-dirty clean)
(ra-notify-watches ra ra.state ra.state)))))) (ra-notify-watches ra (.-state ra) (.-state ra)))))))
(defn- ra-update-watching [ra derefed] (defn- ra-update-watching [ra derefed]
(doseq [w derefed] (doseq [w derefed]
(when-not (contains? ra.watching w) (when-not (contains? (.-watching ra) w)
(add-watch w ra ra-handle-change))) (-add-watch w ra ra-handle-change)))
(doseq [w ra.watching] (doseq [w (.-watching ra)]
(when-not (contains? derefed w) (when-not (contains? derefed w)
(remove-watch w ra))) (-remove-watch w ra)))
(set! ra.watching derefed)) (set! (.-watching ra) derefed))
(deftype Reaction [f ^:mutable state ^:mutable dirty? ^:mutable active? (deftype Reaction [f ^:mutable state ^:mutable dirty? ^:mutable active?
^:mutable watching ^:mutable watches ^:mutable watching ^:mutable watches
@ -299,8 +301,8 @@
derefed (captured this)] derefed (captured this)]
(when (not= derefed watching) (when (not= derefed watching)
(ra-update-watching this derefed)) (ra-update-watching this derefed))
(when-not active? (when-not ^boolean active?
(when debug (swap! -running inc)) (when ^boolean debug (swap! -running inc))
(set! active? true)) (set! active? true))
(set! norun? false) (set! norun? false)
(set! dirty? clean) (set! dirty? clean)
@ -311,7 +313,7 @@
IDeref IDeref
(-deref [this] (-deref [this]
(ra-check-clean this) (ra-check-clean this)
(if (or auto-run (some? *ratom-context*)) (if (or (some? auto-run) (some? *ratom-context*))
(do (do
(notify-deref-watcher! this) (notify-deref-watcher! this)
(if-not (== dirty? clean) (if-not (== dirty? clean)
@ -332,8 +334,8 @@
(set! watching nil) (set! watching nil)
(set! state nil) (set! state nil)
(set! dirty? is-dirty) (set! dirty? is-dirty)
(when active? (when ^boolean active?
(when debug (swap! -running dec)) (when ^boolean debug (swap! -running dec))
(set! active? false)) (set! active? false))
(when on-dispose (when on-dispose
(on-dispose))) (on-dispose)))
@ -350,9 +352,6 @@
IHash IHash
(-hash [this] (goog/getUid this))) (-hash [this] (goog/getUid this)))
(defn- reaction? [ra]
(instance? Reaction ra))
(defn make-reaction [f & {:keys [auto-run on-set on-dispose derefed]}] (defn make-reaction [f & {:keys [auto-run on-set on-dispose derefed]}]
(let [runner (if (= auto-run true) run auto-run) (let [runner (if (= auto-run true) run auto-run)
active (not (nil? derefed)) active (not (nil? derefed))
@ -361,7 +360,7 @@
nil nil nil nil
runner on-set on-dispose false)] runner on-set on-dispose false)]
(when-not (nil? derefed) (when-not (nil? derefed)
(when debug (swap! -running inc)) (when ^boolean debug (swap! -running inc))
(ra-update-watching reaction derefed)) (ra-update-watching reaction derefed))
reaction)) reaction))

View File

@ -13,15 +13,20 @@
(defn dispose [v] (defn dispose [v]
(rv/dispose! v)) (rv/dispose! v))
(def perf-check 0)
(defn ratom-perf [] (defn ratom-perf []
(dbg "ratom-perf") (dbg "ratom-perf")
(let [a (rv/atom 0) (set! perf-check 0)
(let [nite 100000
a (rv/atom 0)
mid (reaction (inc @a)) mid (reaction (inc @a))
res (run! res (run!
(set! perf-check (inc perf-check))
(inc @mid))] (inc @mid))]
(time (dotimes [x 100000] (time (dotimes [x nite]
(swap! a inc))) (swap! a inc)))
(dispose res))) (dispose res)
(assert (= perf-check nite))))
(enable-console-print!) (enable-console-print!)
;; (ratom-perf) ;; (ratom-perf)