Skip to content

Instantly share code, notes, and snippets.

@saikyun
Last active February 4, 2019 13:38
Show Gist options
  • Save saikyun/9109972ffc350ded962aa08184476293 to your computer and use it in GitHub Desktop.
Save saikyun/9109972ffc350ded962aa08184476293 to your computer and use it in GitHub Desktop.
basic profiling
;; Need to (:import System.Diagnostics.Stopwatch)
(defonce times (atom {}))
(defn reset-times! [] (reset! times {}))
(defn avg [vs] (/ (reduce + vs) (count vs)))
(defn avgs [] (into {} (map (fn [ [k vs] ] [k {:total (reduce + vs) :calls (count vs) :max (apply max vs) :min (apply min vs) :avg (avg vs)}]) @times)))
(defn avgs-hm [] (into (sorted-map) (map (fn [[k vs]] [(:total vs) (assoc vs :name k)]) (filter (fn [[k vs]] (or (< 10 (:total vs)) (and (< 10 (:calls vs)) (< 0.1 (:avg vs))))) (avgs)))))
(defmacro trace-time
"Evaluates expr and prints the time it took. Returns the value of
expr."
{:added "1.0"}
[expr & [id]]
`(let [timer# (Stopwatch.)]
(.Start timer#)
(let [ret# ~expr]
(.Stop timer#)
(let [time# (.. timer# -Elapsed -TotalMilliseconds)]
(if ~id
(swap! times update ~id #(conj % time#))
(prn (str "Elapsed time: " time# " msecs"))))
ret#)))
(defn ^{:skip-wiki true} time-fn-call
[name f args]
(trace-time (apply f args)
name))
(defmacro deftime
"Use in place of defn; traces each call/return of this fn, including
arguments. Nested calls to deftrace'd functions will print a
tree-like structure.
The first argument of the form definition can be a doc string"
[name & definition]
(let [doc-string (if (string? (first definition)) (first definition) "")
fn-form (if (string? (first definition)) (rest definition) definition)]
`(do
(declare ~name)
(let [f# (fn ~@fn-form)]
(defn ~name ~doc-string [& args#]
(time-fn-call '~name f# args#))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment