Skip to content

Instantly share code, notes, and snippets.

@whacked
Created June 30, 2019 21:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whacked/9795e0d1d348afdb3c28bf98353564e8 to your computer and use it in GitHub Desktop.
Save whacked/9795e0d1d348afdb3c28bf98353564e8 to your computer and use it in GitHub Desktop.
quick and dirty timing test of clojurescript atom update times: 3 separate atoms, 1 atom, 1 atom + cursors; native atoms and reagent atoms
;; tl;dr: separate atoms is the fastest (1.0x), followed by single atom (1.21x), then separate r/cursors (2.20x)
;; `atom` and `r/atom` have basically equivalent performance when used as-is.
;; the deeper the cursor, the slower the swap.
(let [make-atom r/atom ;; or atom
N 1000000
my-atom1 (make-atom 0)
my-atom2 (make-atom {:nodes [{:id 1} {:id 2}]})
my-atom3 (make-atom {:app-state {:display {:level5 "oliver"}}})
level5-lookup [:app-state :display :level5]
my-atom4 (make-atom {:atom1 @my-atom1
:atom2 @my-atom2
:atom3 @my-atom3})
my-ratom5 (r/atom {:atom1 @my-atom1
:atom2 @my-atom2
:atom3 @my-atom3})
my-ratom5-atom1 (r/cursor my-ratom5 [:atom1])
my-ratom5-atom2 (r/cursor my-ratom5 [:atom2 :nodes])
my-ratom5-atom3 (r/cursor my-ratom5 level5-lookup)
update-atom1 inc
update-atom2-nodes (fn [nodes]
[(first nodes)
{:id @my-atom1}])
print-summary (fn [dt method & outputs]
(js/console.log (str
"### "
dt
" ms for: " method " ###"))
(doseq [output outputs]
(js/console.log (pr-str output))))]
(doseq [method (concat
[:separately
:one-atom]
(if (= make-atom r/atom)
[:with-cursors]))]
(let [t0 (get-now)]
(case method
:separately
(do
(dotimes [n N]
(swap! my-atom1 inc)
(swap! my-atom2
update :nodes
update-atom2-nodes)
(swap! my-atom3
assoc-in
level5-lookup
(str "bobby" @my-atom1)))
(print-summary
(- (get-now) t0)
method
(pr-str @my-atom1)
(pr-str @my-atom2)
(get-in @my-atom3 level5-lookup)))
:one-atom
(do
(dotimes [n N]
(swap! my-atom4
(fn [{:keys [atom1 atom2 atom3]}]
(let [next-atom1 (inc atom1)]
{:atom1 next-atom1
:atom2 (update atom2
:nodes
update-atom2-nodes)
:atom3 (assoc-in atom3
level5-lookup
(str "bobby" next-atom1))}))))
(print-summary
(- (get-now) t0)
method
(:atom1 @my-atom4)
(:atom2 @my-atom4)
(get-in @my-atom4 (concat [:atom3] level5-lookup))))
:with-cursors
(do
(dotimes [n N]
(swap! my-ratom5-atom1 inc)
(swap! my-ratom5-atom2 update-atom2-nodes)
(swap! my-ratom5-atom3 (fn [_]
(str "bobby" @my-ratom5-atom1))))
(print-summary
(- (get-now) t0)
method
@my-ratom5-atom1
(get-in @my-ratom5 [:atom2])
@my-ratom5-atom3))))))
;; ### 3570 ms for: :separately ###
;; "1000000"
;; "{:nodes [{:id 1} {:id 1000000}]}"
;; "bobby1000000"
;; ### 4284 ms for: :one-atom ###
;; 1000000
;; {:nodes [{:id 1} {:id 1000000}]}
;; "bobby1000000"
;; ### 7737 ms for: :with-cursors ###
;; 1000000
;; {:nodes [{:id 1} {:id 1000000}]}
;; "bobby1000000"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment