mirror of https://github.com/status-im/reagent.git
Use plain array instead of set for tracking watched atoms
Turns out to be much, much faster in most cases
This commit is contained in:
parent
7cd2d7d860
commit
e39bb33ccc
|
@ -6,15 +6,16 @@
|
||||||
|
|
||||||
(declare ^:dynamic *ratom-context*)
|
(declare ^:dynamic *ratom-context*)
|
||||||
(defonce cached-reactions {})
|
(defonce cached-reactions {})
|
||||||
|
(defonce ^boolean debug false)
|
||||||
|
(defonce ^boolean silent false)
|
||||||
|
(defonce generation 0)
|
||||||
|
(defonce -running (clojure.core/atom 0))
|
||||||
|
|
||||||
(defn ^boolean reactive? []
|
(defn ^boolean reactive? []
|
||||||
(not (nil? *ratom-context*)))
|
(not (nil? *ratom-context*)))
|
||||||
|
|
||||||
(defonce ^boolean debug false)
|
|
||||||
(defonce ^boolean silent false)
|
|
||||||
(defonce generation 0)
|
|
||||||
|
|
||||||
(defonce -running (clojure.core/atom 0))
|
;;; Utilities
|
||||||
|
|
||||||
(defn running []
|
(defn running []
|
||||||
(+ @-running
|
(+ @-running
|
||||||
|
@ -39,20 +40,28 @@
|
||||||
|
|
||||||
(defn- notify-deref-watcher! [derefable]
|
(defn- notify-deref-watcher! [derefable]
|
||||||
(when-some [obj *ratom-context*]
|
(when-some [obj *ratom-context*]
|
||||||
(let [captured (.-cljsCaptured obj)]
|
(let [c (.-cljsCaptured obj)]
|
||||||
(set! (.-cljsCaptured obj)
|
(if (nil? c)
|
||||||
(if (nil? captured)
|
(set! (.-cljsCaptured obj) (array derefable))
|
||||||
(let [old (.-watching obj)]
|
(when (== -1 (.indexOf c derefable))
|
||||||
(if (and (== 1 (count old))
|
(.push c derefable)))))
|
||||||
(identical? derefable (first old)))
|
nil)
|
||||||
;; Optimize common case of one deref
|
|
||||||
old
|
(defn- ^number arr-len [x]
|
||||||
#{derefable}))
|
(if (nil? x) 0 (alength x)))
|
||||||
(conj captured derefable))))))
|
|
||||||
|
(defn- ^boolean arr-eq [x y]
|
||||||
|
(let [len (arr-len x)]
|
||||||
|
(and (== len (arr-len y))
|
||||||
|
(loop [i 0]
|
||||||
|
(or (== i len)
|
||||||
|
(if (identical? (aget x i) (aget y i))
|
||||||
|
(recur (inc i))
|
||||||
|
false))))))
|
||||||
|
|
||||||
(def reaction-counter 0)
|
(def reaction-counter 0)
|
||||||
|
|
||||||
(defn reaction-key [r]
|
(defn- reaction-key [r]
|
||||||
(if-some [k (.-reaction-id r)]
|
(if-some [k (.-reaction-id r)]
|
||||||
k
|
k
|
||||||
(->> reaction-counter inc
|
(->> reaction-counter inc
|
||||||
|
@ -84,6 +93,7 @@
|
||||||
(pr-writer (binding [*ratom-context* nil] (-deref a)) writer opts)
|
(pr-writer (binding [*ratom-context* nil] (-deref a)) writer opts)
|
||||||
(-write writer ">"))
|
(-write writer ">"))
|
||||||
|
|
||||||
|
|
||||||
;;; Atom
|
;;; Atom
|
||||||
|
|
||||||
(defprotocol IReactiveAtom)
|
(defprotocol IReactiveAtom)
|
||||||
|
@ -340,12 +350,17 @@
|
||||||
|
|
||||||
(_check-clean [this]
|
(_check-clean [this]
|
||||||
(when (== dirtyness maybe-dirty)
|
(when (== dirtyness maybe-dirty)
|
||||||
(let [ar auto-run]
|
(let [ar auto-run
|
||||||
|
len (arr-len watching)]
|
||||||
(set! auto-run nil)
|
(set! auto-run nil)
|
||||||
(doseq [w watching :while (== dirtyness maybe-dirty)]
|
(loop [i 0]
|
||||||
|
(when (< i len)
|
||||||
|
(let [w (aget watching i)]
|
||||||
(when (and (instance? Reaction w)
|
(when (and (instance? Reaction w)
|
||||||
(false? (._check-clean w)))
|
(false? (._check-clean w)))
|
||||||
(._try-run w this)))
|
(._try-run w this)))
|
||||||
|
(when (== dirtyness maybe-dirty)
|
||||||
|
(recur (inc i)))))
|
||||||
(set! auto-run ar))
|
(set! auto-run ar))
|
||||||
(when (== dirtyness maybe-dirty)
|
(when (== dirtyness maybe-dirty)
|
||||||
(set! dirtyness clean)))
|
(set! dirtyness clean)))
|
||||||
|
@ -369,10 +384,12 @@
|
||||||
|
|
||||||
(_update-watching [this derefed]
|
(_update-watching [this derefed]
|
||||||
(doseq [w derefed]
|
(doseq [w derefed]
|
||||||
(when-not (contains? watching w)
|
(when (or (nil? watching)
|
||||||
|
(== -1 (.indexOf watching w)))
|
||||||
(-add-watch w this handle-reaction-change)))
|
(-add-watch w this handle-reaction-change)))
|
||||||
(doseq [w watching]
|
(doseq [w watching]
|
||||||
(when-not (contains? derefed w)
|
(when (or (nil? derefed)
|
||||||
|
(== -1 (.indexOf derefed w)))
|
||||||
(-remove-watch w this)))
|
(-remove-watch w this)))
|
||||||
(set! watching derefed)
|
(set! watching derefed)
|
||||||
nil)
|
nil)
|
||||||
|
@ -394,7 +411,7 @@
|
||||||
(let [oldstate state
|
(let [oldstate state
|
||||||
res (capture-derefed f this)
|
res (capture-derefed f this)
|
||||||
derefed (-captured this)]
|
derefed (-captured this)]
|
||||||
(when (not= derefed watching)
|
(when-not (arr-eq derefed watching)
|
||||||
(._update-watching this derefed))
|
(._update-watching this derefed))
|
||||||
(set! dirtyness clean)
|
(set! dirtyness clean)
|
||||||
(when-not nocache?
|
(when-not nocache?
|
||||||
|
|
Loading…
Reference in New Issue