Simplify with-let and tweak performance

This commit is contained in:
Dan Holmsand 2015-09-26 13:12:59 +02:00
parent 5fceda2aae
commit 415ecd64fd
3 changed files with 42 additions and 43 deletions

View File

@ -17,15 +17,7 @@
(defmacro with-let [bindings & body] (defmacro with-let [bindings & body]
(assert (vector? bindings)) (assert (vector? bindings))
(let [v (gensym "bind-v") (let [v (gensym "bind-v")
bs (->> bindings key (str v)
(map-indexed (fn [i x]
(if (even? i)
x
(let [pos (quot i 2)]
`(if (> (alength ~v) ~pos)
(aget ~v ~pos)
(aset ~v ~pos ~x))))))
vec)
[forms destroy] (let [fin (last body)] [forms destroy] (let [fin (last body)]
(if (and (list? fin) (if (and (list? fin)
(= 'finally (first fin))) (= 'finally (first fin)))
@ -35,18 +27,20 @@
`(cljs.core/js-obj)) `(cljs.core/js-obj))
asserting (if *assert* true false)] asserting (if *assert* true false)]
`(let [destroy-obj# ~destroy-obj `(let [destroy-obj# ~destroy-obj
~v (reagent.ratom/get-cached-values (quote ~v) destroy-obj#)] ~v (reagent.ratom/with-let-value ~key destroy-obj#)]
(when ~asserting (when ~asserting
(when-some [c# reagent.ratom/*ratom-context*] (when-some [c# reagent.ratom/*ratom-context*]
(when (== (.-ratomGeneration c#) (when (== (.-generation ~v) (.-ratomGeneration c#))
(.-generation ~v))
(d/error "Warning: The same with-let is being used more than once in the same reactive context.")) (d/error "Warning: The same with-let is being used more than once in the same reactive context."))
(set! (.-generation ~v) (.-ratomGeneration c#)))) (set! (.-generation ~v) (.-ratomGeneration c#))))
(let ~bs (when (zero? (alength ~v))
(let [destroy# ~destroy (aset ~v 0 (let ~bindings
res# (do ~@forms)] (fn []
(when-not (nil? destroy#) (let [res# (do ~@forms)]
(if (reagent.ratom/reactive?) (when-some [destroy# ~destroy]
(set! (.-destroy destroy-obj#) destroy#) (if (reagent.ratom/reactive?)
(destroy#))) (when (nil? (.-destroy destroy-obj#))
res#))))) (set! (.-destroy destroy-obj#) destroy#))
(destroy#)))
res#)))))
((aget ~v 0)))))

View File

@ -1,6 +1,6 @@
(ns reagent.ratom (ns reagent.ratom
(:refer-clojure :exclude [atom]) (:refer-clojure :exclude [atom])
(:require-macros [reagent.ratom]) (:require-macros [reagent.ratom :refer [with-let]])
(:require [reagent.impl.util :as util] (:require [reagent.impl.util :as util]
[reagent.debug :refer-macros [dbg log warn dev?]])) [reagent.debug :refer-macros [dbg log warn dev?]]))
@ -45,6 +45,15 @@
(conj (if (nil? captured) #{} captured) (conj (if (nil? captured) #{} captured)
derefable)))))) derefable))))))
(def reaction-counter 0)
(defn reaction-key [r]
(if-some [k (.-reaction-id r)]
k
(->> reaction-counter inc
(set! reaction-counter)
(set! (.-reaction-id r)))))
(defn- check-watches [old new] (defn- check-watches [old new]
(when debug (when debug
(swap! -running + (- (count new) (count old)))) (swap! -running + (- (count new) (count old))))
@ -131,8 +140,10 @@
(dissoc cached-reactions key)) (dissoc cached-reactions key))
(when (some? obj) (when (some? obj)
(set! (.-reaction obj) nil)) (set! (.-reaction obj) nil))
(when (some-> destroy .-destroy some?) (when-not (or (nil? destroy)
(.destroy destroy)))) (nil? (.-destroy destroy)))
(.destroy destroy))
nil))
v (-deref r)] v (-deref r)]
(set! cached-reactions (assoc cached-reactions key r)) (set! cached-reactions (assoc cached-reactions key r))
(when (some? obj) (when (some? obj)
@ -269,20 +280,10 @@
;;; with-let support ;;; with-let support
(def reaction-counter 0) (defn with-let-value [key destroy]
(if-some [c *ratom-context*]
(defn reaction-key [] (cached-reaction array [(reaction-key c) key]
(when-some [c *ratom-context*] nil destroy)
(if-some [k (.-reaction-id c)]
k
(->> reaction-counter inc
(set! reaction-counter)
(set! (.-reaction-id c))))))
(defn get-cached-values [key destroy]
(if-some [k (reaction-key)]
(cached-reaction #(array)
[k key] nil destroy)
(array))) (array)))
@ -357,7 +358,7 @@
(when (== dirtyness maybe-dirty) (when (== dirtyness maybe-dirty)
(let [ar auto-run] (let [ar auto-run]
(set! auto-run nil) (set! auto-run nil)
(doseq [w watching] (doseq [w watching :while (== dirtyness maybe-dirty)]
(when (and (instance? Reaction w) (when (and (instance? Reaction w)
(not (-check-clean w))) (not (-check-clean w)))
(._try-run this w))) (._try-run this w)))
@ -466,7 +467,7 @@
(-write writer ">")) (-write writer ">"))
IHash IHash
(-hash [this] (goog/getUid this))) (-hash [this] (reaction-key this)))
;;; Queueing ;;; Queueing
@ -596,9 +597,13 @@
(set! perf-check 0) (set! perf-check 0)
(let [nite 100000 (let [nite 100000
a (atom 0) a (atom 0)
mid (make-reaction (fn [] (inc @a))) f (fn []
;; (with-let [x 1])
(quot @a 10))
mid (make-reaction f)
res (make-reaction (fn [] res (make-reaction (fn []
(set! perf-check (inc perf-check)) (set! perf-check (inc perf-check))
;; @(track f)
(inc @mid)) (inc @mid))
:auto-run true)] :auto-run true)]
@res @res

View File

@ -134,19 +134,19 @@
(reset! a 2) (reset! a 2)
(sync) (sync)
(is (= @b-changed 3)) (is (<= 2 @b-changed 3))
(is (= @c-changed 1)) (is (= @c-changed 1))
(is (= @res (+ 10 @a))) (is (= @res (+ 10 @a)))
(reset! a 3) (reset! a 3)
(sync) (sync)
(is (= @b-changed 3)) (is (<= 2 @b-changed 3))
(is (= @c-changed 2)) (is (= @c-changed 2))
(is (= @res (+ 10 @a))) (is (= @res (+ 10 @a)))
(reset! a 3) (reset! a 3)
(sync) (sync)
(is (= @b-changed 3)) (is (<= 2 @b-changed 3))
(is (= @c-changed 2)) (is (= @c-changed 2))
(is (= @res (+ 10 @a))) (is (= @res (+ 10 @a)))