Skip to content

Instantly share code, notes, and snippets.

@fogus
Last active April 24, 2026 14:07
Show Gist options
  • Select an option

  • Save fogus/eb44595bc2664a5520f613339db9b15c to your computer and use it in GitHub Desktop.

Select an option

Save fogus/eb44595bc2664a5520f613339db9b15c to your computer and use it in GitHub Desktop.
(import [clojure.lang RT])
(set! *warn-on-reflection* true)
(let [nf (Object.)]
(defn get-throwing [m k]
(let [v (RT/get m k nf)]
(if (identical? v nf)
(throw (ex-info "Missing key" {:key k}))
v))))
(let [nf (Object.)]
(defn get-sentinel [m k]
(let [v (RT/get m k nf)]
(if (identical? v nf) 0 v))))
(defn make-test-map [n]
(reduce (fn [m i]
(assoc m (keyword (str "kword-" i)) i))
{}
(range n)))
(defn- make-bench* [getf]
`(fn [^long iter# ^long inner# ^long n#]
(let [m# (make-test-map n#)
ks# (to-array (keys m#))]
(dotimes [i# iter#]
(let [start# (System/nanoTime)
total#
(loop [c# 0
total# 0]
(if (< c# inner#)
(recur (inc c#) (+ total# (long (~getf m# (aget ks# (rem c# n#))))))
total#))]
(println {:which (quote ~getf)
:iter i#
:total total#
:ms (quot (- (System/nanoTime) start#) 1000000)}))))))
(defmacro make-bench [getf] (make-bench* getf))
(def bench-get (make-bench get))
(def bench-get-throwing (make-bench get-throwing))
(def bench-get-sentinel (make-bench get-sentinel))
(defn bench
"clj -X:bench :which :get :iter 100 :inner 10000 :N 100"
[& {:keys [which iter inner n]}]
(which iter inner n))
(comment
(map #(bench :which % :iter 10 :inner 200000000 :n 6)
[#'bench-get #'bench-get-throwing #'bench-get-sentinel])
;{:total 499999996, :which get, :iter 9, :ms 995}
;{:total 499999996, :which get-throwing, :iter 9, :ms 1045}
;{:total 499999996, :which get-sentinel, :iter 9, :ms 1048}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment