10x perf improvement on safe-merge
safe merge was using way too much inefficient code for such an important function it is rewritten using a reduce. the performance improvement is 10 times and should really show up when adding messages in repl session the new merge was much slower on the error case of merging fx with common keys but it must never happen in production as it means the app is broken status-im.utils.fx> (time (dotimes [x 100] (fast-merge {:a 1 :b 2 :filters/load-filters [{:a 1 :b 2}]} {:c 3 :filters/load-filters [{:d 1 :b x}]}))) "Elapsed time: 19.000000 msecs" nil status-im.utils.fx> (time (dotimes [x 100] (safe-merge {:a 1 :b 2 :filters/load-filters [{:a 1 :b 2}]} {:c 3 :filters/load-filters [{:d 1 :b x}]}))) "Elapsed time: 183.000000 msecs" status-im.utils.fx> (time (dotimes [x 100] (fast-merge {:a 1 :c 2 :filters/load-filters [{:a 1 :b 2}]} {:c 3 :filters/load-filters [{:d 1 :b x}]}))) "Elapsed time: 2224.000000 msecs"
This commit is contained in:
parent
747dec908e
commit
ee042bd1c4
|
@ -4,14 +4,14 @@
|
|||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[taoensso.timbre :as log]
|
||||
status-im.utils.handlers)
|
||||
(:refer-clojure :exclude [merge]))
|
||||
(:refer-clojure :exclude [merge reduce]))
|
||||
|
||||
(defn- update-db [cofx fx]
|
||||
(if-let [db (:db fx)]
|
||||
(assoc cofx :db db)
|
||||
cofx))
|
||||
|
||||
(def ^:private mergable-keys
|
||||
(def ^:private mergeable-keys
|
||||
#{:chat-received-message/add-fx
|
||||
:filters/load-filters
|
||||
:pairing/set-installation-metadata
|
||||
|
@ -27,16 +27,17 @@
|
|||
(defn- safe-merge [fx new-fx]
|
||||
(if (:merging-fx-with-common-keys fx)
|
||||
fx
|
||||
(let [common-keys (set/intersection (into #{} (keys fx))
|
||||
(into #{} (keys new-fx)))]
|
||||
(if (empty? (set/difference common-keys (conj mergable-keys :db)))
|
||||
(clojure.core/merge (apply dissoc fx mergable-keys)
|
||||
(apply dissoc new-fx mergable-keys)
|
||||
(merge-with into
|
||||
(select-keys fx mergable-keys)
|
||||
(select-keys new-fx mergable-keys)))
|
||||
(do (log/error "Merging fx with common-keys: " common-keys)
|
||||
{:merging-fx-with-common-keys common-keys})))))
|
||||
(clojure.core/reduce (fn [merged-fx [k v]]
|
||||
(if (= :db k)
|
||||
(assoc merged-fx :db v)
|
||||
(if (get merged-fx k)
|
||||
(if (mergeable-keys k)
|
||||
(update merged-fx k into v)
|
||||
(do (log/error "Merging fx with common-key: " k v)
|
||||
(reduced {:merging-fx-with-common-keys k})))
|
||||
(assoc merged-fx k v))))
|
||||
fx
|
||||
new-fx)))
|
||||
|
||||
(defn merge
|
||||
"Takes a map of co-effects and forms as argument.
|
||||
|
@ -51,7 +52,7 @@
|
|||
(let [[first-arg & rest-args] args
|
||||
initial-fxs? (map? first-arg)
|
||||
fx-fns (if initial-fxs? rest-args args)]
|
||||
(reduce (fn [fxs fx-fn]
|
||||
(clojure.core/reduce (fn [fxs fx-fn]
|
||||
(let [updated-cofx (update-db cofx fxs)]
|
||||
(if fx-fn
|
||||
(safe-merge fxs (fx-fn updated-cofx))
|
||||
|
|
Loading…
Reference in New Issue