Last active
October 17, 2024 14:16
-
-
Save alexander-yakushev/63515455759e66bfa19dbaa126fccf56 to your computer and use it in GitHub Desktop.
System-wide tools.deps configuration and code (for London Clojurians meetup 05'23)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{:deps {org.clojure/clojure {:mvn/version "1.12.0-alpha3"}} | |
:aliases {:dev {:extra-deps | |
{com.clojure-goes-fast/clj-async-profiler {:mvn/version "1.0.4"} | |
com.clojure-goes-fast/clj-java-decompiler {:mvn/version "0.3.4"} | |
com.clojure-goes-fast/clj-memory-meter {:mvn/version "0.3.0"}} | |
:jvm-opts ["-Djdk.attach.allowAttachSelf" | |
"-XX:+UseG1GC" | |
"-XX:-OmitStackTraceInFastThrow" | |
"-XX:+UnlockDiagnosticVMOptions" "-XX:+DebugNonSafepoints"]} | |
:user {:main-opts ["-e" "(load-file,(str,(System/getProperty,\"user.home\"),\"/.clojure/user.clj\"))"]} | |
:cider {:extra-deps | |
{nrepl/nrepl {:mvn/version "0.9.0"} | |
cider/cider-nrepl {:mvn/version "0.30.0"} | |
refactor-nrepl/refactor-nrepl {:mvn/version "3.6.0"}} | |
:main-opts ["-m" "nrepl.cmdline" "--middleware" "[refactor-nrepl.middleware/wrap-refactor,cider.nrepl/cider-middleware]"]}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Additional code to be loaded within user namespace in :dev profile. | |
(in-ns 'user) | |
(let [time* | |
(fn [^long duration-in-ms f] | |
(let [^com.sun.management.ThreadMXBean bean (java.lang.management.ManagementFactory/getThreadMXBean) | |
bytes-before (.getCurrentThreadAllocatedBytes bean) | |
duration (* duration-in-ms 1000000) | |
start (System/nanoTime) | |
first-res (f) | |
delta (- (System/nanoTime) start) | |
deadline (+ start duration) | |
tight-iters (max (quot (quot duration delta) 10) 1)] | |
(loop [i 1] | |
(let [now (System/nanoTime)] | |
(if (< now deadline) | |
(do (dotimes [_ tight-iters] (f)) | |
(recur (+ i tight-iters))) | |
(let [i' (double i) | |
bytes-after (.getCurrentThreadAllocatedBytes bean) | |
t (/ (- now start) i')] | |
(println | |
(format "Time per call: %s Alloc per call: %,.0fb Iterations: %d" | |
(cond (< t 1e3) (format "%.0f ns" t) | |
(< t 1e6) (format "%.2f us" (/ t 1e3)) | |
(< t 1e9) (format "%.2f ms" (/ t 1e6)) | |
:else (format "%.2f s" (/ t 1e9))) | |
(/ (- bytes-after bytes-before) i') | |
i)) | |
first-res))))))] | |
(defmacro time+ | |
"Like `time`, but runs the supplied body for 2000 ms and prints the average | |
time for a single iteration. Custom total time in milliseconds can be provided | |
as the first argument. Returns the returned value of the FIRST iteration." | |
[?duration-in-ms & body] | |
(let [[duration body] (if (integer? ?duration-in-ms) | |
[?duration-in-ms body] | |
[2000 (cons ?duration-in-ms body)])] | |
`(~time* ~duration (fn [] ~@body))))) | |
(defn heap [] | |
(let [u (.getHeapMemoryUsage (java.lang.management.ManagementFactory/getMemoryMXBean)) | |
used (/ (.getUsed u) 1e6) | |
total (/ (.getMax u) 1e6)] | |
(format "Used: %.0f/%.0f MB (%.0f%%), free: %.0f MB" used total (/ used total 0.01) | |
(/ (.freeMemory (Runtime/getRuntime)) 1e6)))) | |
(defmacro debugging-tools [] | |
'(do | |
(require '[clj-async-profiler.core :as prof]) | |
(require '[clj-java-decompiler.core :refer [decompile]]) | |
(require '[clj-memory-meter.core :as mm]) | |
(.refer *ns* 'time+ #'user/time+) | |
(.refer *ns* 'heap #'user/heap))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment