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]
(assert (vector? bindings))
(let [v (gensym "bind-v")
bs (->> bindings
(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)
key (str v)
[forms destroy] (let [fin (last body)]
(if (and (list? fin)
(= 'finally (first fin)))
@ -35,18 +27,20 @@
`(cljs.core/js-obj))
asserting (if *assert* true false)]
`(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-some [c# reagent.ratom/*ratom-context*]
(when (== (.-ratomGeneration c#)
(.-generation ~v))
(when (== (.-generation ~v) (.-ratomGeneration c#))
(d/error "Warning: The same with-let is being used more than once in the same reactive context."))
(set! (.-generation ~v) (.-ratomGeneration c#))))
(let ~bs
(let [destroy# ~destroy
res# (do ~@forms)]
(when-not (nil? destroy#)
(when (zero? (alength ~v))
(aset ~v 0 (let ~bindings
(fn []
(let [res# (do ~@forms)]
(when-some [destroy# ~destroy]
(if (reagent.ratom/reactive?)
(set! (.-destroy destroy-obj#) destroy#)
(when (nil? (.-destroy destroy-obj#))
(set! (.-destroy destroy-obj#) destroy#))
(destroy#)))
res#)))))
((aget ~v 0)))))

View File

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

View File

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