From a91a8401d62ca3dbc5a73bc17e3d3e3a0ca68791 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 11 Apr 2020 10:20:58 +0200 Subject: [PATCH] :sparkles: More improvements to perf namespace. --- frontend/src/uxbox/util/perf.clj | 17 ++++++++ frontend/src/uxbox/util/perf.cljs | 69 ++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 frontend/src/uxbox/util/perf.clj diff --git a/frontend/src/uxbox/util/perf.clj b/frontend/src/uxbox/util/perf.clj new file mode 100644 index 000000000..30d01d6a0 --- /dev/null +++ b/frontend/src/uxbox/util/perf.clj @@ -0,0 +1,17 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) 2020 UXBOX Labs SL + +(ns uxbox.util.perf + "Performance profiling for react components.") + +(defmacro with-measure + [name & body] + `(let [start# (uxbox.util.perf/timestamp) + res# (do ~@body) + end# (uxbox.util.perf/timestamp)] + (uxbox.util.perf/register-measure ~name (- end# start#)) + res#)) + diff --git a/frontend/src/uxbox/util/perf.cljs b/frontend/src/uxbox/util/perf.cljs index 09d193dc2..daf5c8d7c 100644 --- a/frontend/src/uxbox/util/perf.cljs +++ b/frontend/src/uxbox/util/perf.cljs @@ -6,6 +6,7 @@ (ns uxbox.util.perf "Performance profiling for react components." + (:require-macros [uxbox.util.perf]) (:require [uxbox.util.math :as math] [rumext.alpha :as mf] [goog.functions :as f] @@ -35,29 +36,77 @@ ;; (println (str "[perf|" ~name "] => " time#)) ;; res#))) +(defn tdigest + [] + (specify! (td/TDigest.) + ITransientCollection + (-conj! [this n] + (.push this n) + this) + + (-persistent! [this] + this))) + +(defn timestamp + [] + (js/performance.now)) + +(def registry (js/Map.)) + +(def register-measure + (let [insert! + (fn [name measure] + (let [td (.get registry name)] + (if td + (conj! td measure) + (.set registry name (conj! (tdigest) measure))))) + + print-single-summary! + (fn [name td] + (js/console.log (str "[measure: " name "] " + "samples=" (unchecked-get td "n") "\n" + "Q50=" (.percentile td 0.50) "\n" + "Q75=" (.percentile td 0.75) "\n" + "Q95=" (.percentile td 0.90) "\n" + "MAX=" (.percentile td 1)))) + print-summary! + (f/debounce + #(.forEach registry (fn [td name] (print-single-summary! name td))) + 500)] + (fn [name measure] + (insert! name measure) + (print-summary!)))) + +(defn mesurable + [name f] + (fn [& args] + (uxbox.util.perf/with-measure name + (apply f args)))) + (defn on-render-factory [label] - (let [buf (td/TDigest.) + (let [td (tdigest) log (f/debounce - (fn [phase buf] + (fn [phase td] (js/console.log (str "[profile: " label " (" phase ")] " - "samples=" (unchecked-get buf "n") "\n" - "Q50=" (.percentile buf 0.50) "\n" - "Q75=" (.percentile buf 0.75) "\n" - "Q95=" (.percentile buf 0.90) "\n" - "MAX=" (.percentile buf 1)))) + "samples=" (unchecked-get td "n") "\n" + "Q50=" (.percentile td 0.50) "\n" + "Q75=" (.percentile td 0.75) "\n" + "Q95=" (.percentile td 0.90) "\n" + "MAX=" (.percentile td 1)))) 300)] (fn [id phase adur, bdur, st, ct, itx] - (.push buf adur) - (log phase buf)))) + (conj! td adur) + (log phase td)))) (mf/defc profiler {::mf/wrap-props false} [props] (let [children (unchecked-get props "children") label (unchecked-get props "label") - enabled? (or (unchecked-get props "enabled") true) + enabled? (unchecked-get props "enabled") + enabled? (if (nil? enabled?) true enabled?) on-render (mf/use-memo (mf/deps label) #(on-render-factory label))]