Skip to content

Instantly share code, notes, and snippets.

@borkdude
Last active April 6, 2021 11:38
Show Gist options
  • Save borkdude/e6f0b12f9352f3375e5f3277d2aba6c9 to your computer and use it in GitHub Desktop.
Save borkdude/e6f0b12f9352f3375e5f3277d2aba6c9 to your computer and use it in GitHub Desktop.
Reports number of used k/v pairs in assoc to gather data for https://clojure.atlassian.net/browse/CLJ-1656
#!/usr/bin/env bash
#_" -*- mode: clojure; -*-"
#_(
"exec" "clojure" "-Sdeps" "{:deps {borkdude/grasp {:git/url \"https://github.com/borkdude/grasp\" :sha \"6315cea8c0b6dafc7b1eef9ccd03d6d5590d2045\"}}}" "-M" "$0" "$@"
)
(require '[clojure.java.io :as io]
'[clojure.spec.alpha :as s]
'[clojure.string :as str]
'[grasp.api :as g])
(def files (filter #(or (str/ends-with? % ".jar")
(str/ends-with? % ".clj")
(str/ends-with? % ".cljc")
(str/ends-with? % ".cljs"))
(file-seq (io/file "."))))
(def results (atom []))
(def error-log (io/file (System/getProperty "java.io.tmpdir") "assoc_pairs_errors.txt"))
(def errors? (atom false))
(defn write-errors [s]
(when-not (str/blank? s)
(reset! errors? true)
(locking error-log
(spit error-log s :append true))))
(def progress-indicator (cycle ["-" "\\" "|" "/"]))
(defn grasp-task [^java.util.concurrent.LinkedBlockingDeque deque]
(loop []
(when-let [[file progress] (.pollFirst deque)]
(try
(binding [*out* *err*]
(print (str "\r" progress)) (flush))
(let [errors (java.io.StringWriter.)]
(binding [*err* errors]
(let [found (g/grasp file (g/seq 'assoc (s/+ any?)))]
(swap! results conj (doall found))))
(write-errors (str errors)))
(catch Exception e (binding [*out* *err*]
(prn e))))
(recur))))
(defn parallel-grasp [files]
(let [files-and-progress (map (fn [file progress]
[file progress])
files progress-indicator)
deque (java.util.concurrent.LinkedBlockingDeque. ^java.util.List files-and-progress)
cnt (+ 2 (int (* 0.6 (.. Runtime getRuntime availableProcessors))))
latch (java.util.concurrent.CountDownLatch. cnt)
es (java.util.concurrent.Executors/newFixedThreadPool cnt)]
(dotimes [_ cnt]
(.execute es
(bound-fn []
(grasp-task deque)
(.countDown latch))))
(.await latch)
(.shutdown es)))
(parallel-grasp files)
(print "\r") (flush)
(when @errors?
(binding [*out* *err*]
(println "Logged errors to" (.getPath error-log))))
(defn kv-pairs [form]
(let [args (count (nnext form))
pairs (if (even? args)
(/ args 2)
;; account for threading macro usage
(/ (inc args) 2))]
pairs))
(defn left-pad [s max]
(let [s (str s)
len (count s)]
(str (apply str (repeat (- max len) " ")) s)))
(defn render! [report]
(let [total (apply + (map second report))
sorted (sort-by second > report)]
(println "Total:" total)
(doseq [[kvs freq] sorted]
(print (str (left-pad kvs 2) ": "))
(let [percentage (* 100 (double (/ freq total)))
rounded (Math/round percentage)]
(dotimes [_ (max rounded 1)]
(print "*"))
(print (format " (%s, %.2f%%)" freq percentage)))
(println))))
(defn report! [results]
(let [pairs (map kv-pairs results)
freqs (frequencies pairs)]
(render! freqs)))
(report! (mapcat identity @results))
@borkdude
Copy link
Author

borkdude commented Dec 21, 2020

borkdude@MBP2019 ~/.m2 $ ~/Dropbox/temp/assoc_pairs.clj
Logged errors to /var/folders/2m/h3cvrr1x4296p315vbk7m32c0000gp/T/assoc_pairs_errors.txt
Total: 25629
 1: ********************************************************************************** (20911, 81,59%)
 2: ************ (3036, 11,85%)
 3: **** (1085, 4,23%)
 4: * (327, 1,28%)
 5: * (126, 0,49%)
 6: * (64, 0,25%)
 7: * (33, 0,13%)
10: * (23, 0,09%)
 8: * (11, 0,04%)
 9: * (6, 0,02%)
14: * (4, 0,02%)
 0: * (1, 0,00%)
12: * (1, 0,00%)
16: * (1, 0,00%)

Related issue:

Vote if you find this important.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment