Skip to content

Instantly share code, notes, and snippets.

@hiredman
Created Sep 11, 2014
Embed
What would you like to do?
(defn double-map [f]
(let [^clojure.lang.IFn$DD f f]
(fn [f1]
(if (instance? clojure.lang.IFn$DDD f1)
(let [^clojure.lang.IFn$DDD f1 f1]
(fn
([] (f1))
(^double [^double result] (.invokePrim ^clojure.lang.IFn$DD f1 result))
(^double [^double result ^double input]
(.invokePrim f1 result (.invokePrim f input)))
([result input & inputs]
(.invokePrim f1 (double result) (double (apply f input inputs))))))
(let [^clojure.lang.IFn$ODO f1 f1]
(fn
([] (f1))
([^double result]
(.invokePrim ^clojure.lang.IFn$DO f1 result))
([result ^double input]
(.invokePrim f1 result (.invokePrim f input)))
([result input & inputs]
(.invokePrim f1 (double result) (double (apply f input inputs))))))))))
(defn double-sum ^double [^double a ^double b]
(+ a b))
(defn double-inc ^double [^double d]
(inc d))
(defprotocol PrimitiveReduce
(coll-reduce [coll fun init]))
(extend-protocol PrimitiveReduce
(Class/forName "[D")
(coll-reduce [coll fun init]
(let [^doubles coll coll]
(if (instance? clojure.lang.IFn$DDD fun)
(areduce coll idx ret init (.invokePrim ^clojure.lang.IFn$DDD fun ret (aget coll idx)))
(areduce coll idx ret init (.invokePrim ^clojure.lang.IFn$ODO fun ret (aget coll idx)))))))
(def da (into-array Double/TYPE (map double (range 1e3))))
(defn primitive-reduce [fun init coll]
(coll-reduce coll fun init))
(use 'criterium.core)
(defn f []
(println "plain")
(bench (reduce + 0.0 (map inc da)))
(println)
(println "reducer")
(bench (reduce ((map inc) +) 0.0 da))
(println)
(println "double ops")
(bench (reduce ((map double-inc) double-sum) 0.0 da))
(println)
(println "double map")
(bench (reduce ((double-map double-inc) double-sum) 0.0 da))
(println)
(println "double reduce")
(bench (primitive-reduce ((double-map double-inc) double-sum) 0.0 da))
(println)
(println "loop")
(bench (let [^doubles da da
l (alength da)]
(loop [idx 0
result 0.0]
(if (> l idx)
(recur (inc idx)
(double-sum result (double-inc (aget da idx))))
result)))))
;; user=> (f)
;; plain
;; WARNING: Final GC required 2.197171823200119 % of runtime
;; Evaluation count : 249960 in 60 samples of 4166 calls.
;; Execution time mean : 235.675839 µs
;; Execution time std-deviation : 20.719096 µs
;; Execution time lower quantile : 209.601541 µs ( 2.5%)
;; Execution time upper quantile : 277.664605 µs (97.5%)
;; Overhead used : 2.809414 ns
;; Found 1 outliers in 60 samples (1.6667 %)
;; low-severe 1 (1.6667 %)
;; Variance from outliers : 63.5764 % Variance is severely inflated by outliers
;; reducer
;; Evaluation count : 1989300 in 60 samples of 33155 calls.
;; Execution time mean : 33.798007 µs
;; Execution time std-deviation : 2.815327 µs
;; Execution time lower quantile : 29.539884 µs ( 2.5%)
;; Execution time upper quantile : 40.746241 µs (97.5%)
;; Overhead used : 2.809414 ns
;; Found 2 outliers in 60 samples (3.3333 %)
;; low-severe 2 (3.3333 %)
;; Variance from outliers : 61.8279 % Variance is severely inflated by outliers
;; double ops
;; Evaluation count : 2980020 in 60 samples of 49667 calls.
;; Execution time mean : 23.134346 µs
;; Execution time std-deviation : 3.444387 µs
;; Execution time lower quantile : 19.855205 µs ( 2.5%)
;; Execution time upper quantile : 29.790305 µs (97.5%)
;; Overhead used : 2.809414 ns
;; Found 4 outliers in 60 samples (6.6667 %)
;; low-severe 2 (3.3333 %)
;; low-mild 2 (3.3333 %)
;; Variance from outliers : 84.1512 % Variance is severely inflated by outliers
;; double map
;; Evaluation count : 2014980 in 60 samples of 33583 calls.
;; Execution time mean : 26.210704 µs
;; Execution time std-deviation : 1.886347 µs
;; Execution time lower quantile : 23.339536 µs ( 2.5%)
;; Execution time upper quantile : 29.825937 µs (97.5%)
;; Overhead used : 2.809414 ns
;; Found 1 outliers in 60 samples (1.6667 %)
;; low-severe 1 (1.6667 %)
;; Variance from outliers : 53.4791 % Variance is severely inflated by outliers
;; double reduce
;; Evaluation count : 7155420 in 60 samples of 119257 calls.
;; Execution time mean : 7.658654 µs
;; Execution time std-deviation : 844.754759 ns
;; Execution time lower quantile : 6.482219 µs ( 2.5%)
;; Execution time upper quantile : 9.397704 µs (97.5%)
;; Overhead used : 2.809414 ns
;; Found 2 outliers in 60 samples (3.3333 %)
;; low-severe 2 (3.3333 %)
;; Variance from outliers : 73.7960 % Variance is severely inflated by outliers
;; loop
;; Evaluation count : 11855820 in 60 samples of 197597 calls.
;; Execution time mean : 5.180858 µs
;; Execution time std-deviation : 440.035956 ns
;; Execution time lower quantile : 4.429034 µs ( 2.5%)
;; Execution time upper quantile : 6.014579 µs (97.5%)
;; Overhead used : 2.809414 ns
;; nil
;; user=>
(definterface DoubleBuilder
(putIn [^double d]))
(defn put-in [^DoubleBuilder db ^double d]
(.putIn db d)
db)
(deftype DB [^long ^:unsynchronized-mutable idx ^doubles da]
DoubleBuilder
(putIn [_ d]
(aset da idx d)
(set! idx (inc idx)))
clojure.lang.IDeref
(deref [_]
da))
(defn f []
(println "plain")
(bench (deref (reduce put-in (DB. 0 (double-array (count da))) (map inc da))))
(println)
(println "reducer")
(bench (deref (reduce ((map inc) put-in) (DB. 0 (double-array (count da))) da)))
(println)
(println "double ops")
(bench (deref (reduce ((map double-inc) put-in) (DB. 0 (double-array (count da))) da)))
(println)
(println "double map")
(bench (deref (reduce ((double-map double-inc) put-in) (DB. 0 (double-array (count da))) da)))
(println)
(println "double reduce")
(bench (deref (primitive-reduce ((double-map double-inc) put-in) (DB. 0 (double-array (count da))) da)))
(println)
(println "loop")
(bench (let [^doubles da da
l (alength da)]
(loop [idx 0
result (DB. 0 (double-array (count da)))]
(if (> l idx)
(recur (inc idx)
(put-in result (double-inc (aget da idx))))
result)))))
;; user=> (f)
;; plain
;; Evaluation count : 289380 in 60 samples of 4823 calls.
;; Execution time mean : 219.620712 µs
;; Execution time std-deviation : 39.883605 µs
;; Execution time lower quantile : 175.426963 µs ( 2.5%)
;; Execution time upper quantile : 322.772096 µs (97.5%)
;; Overhead used : 2.437790 ns
;; Found 3 outliers in 60 samples (5.0000 %)
;; low-severe 2 (3.3333 %)
;; low-mild 1 (1.6667 %)
;; Variance from outliers : 89.3604 % Variance is severely inflated by outliers
;; reducer
;; Evaluation count : 2025120 in 60 samples of 33752 calls.
;; Execution time mean : 30.811093 µs
;; Execution time std-deviation : 4.096367 µs
;; Execution time lower quantile : 26.984407 µs ( 2.5%)
;; Execution time upper quantile : 40.097285 µs (97.5%)
;; Overhead used : 2.437790 ns
;; Found 5 outliers in 60 samples (8.3333 %)
;; low-severe 4 (6.6667 %)
;; low-mild 1 (1.6667 %)
;; Variance from outliers : 80.6841 % Variance is severely inflated by outliers
;; double ops
;; Evaluation count : 1900260 in 60 samples of 31671 calls.
;; Execution time mean : 27.680658 µs
;; Execution time std-deviation : 2.151124 µs
;; Execution time lower quantile : 24.967282 µs ( 2.5%)
;; Execution time upper quantile : 32.293927 µs (97.5%)
;; Overhead used : 2.437790 ns
;; Found 1 outliers in 60 samples (1.6667 %)
;; low-severe 1 (1.6667 %)
;; Variance from outliers : 58.4476 % Variance is severely inflated by outliers
;; double map
;; Evaluation count : 2458800 in 60 samples of 40980 calls.
;; Execution time mean : 21.708545 µs
;; Execution time std-deviation : 1.245046 µs
;; Execution time lower quantile : 19.713619 µs ( 2.5%)
;; Execution time upper quantile : 24.612911 µs (97.5%)
;; Overhead used : 2.437790 ns
;; Found 3 outliers in 60 samples (5.0000 %)
;; low-severe 3 (5.0000 %)
;; Variance from outliers : 41.8467 % Variance is moderately inflated by outliers
;; double reduce
;; Evaluation count : 4641960 in 60 samples of 77366 calls.
;; Execution time mean : 14.409706 µs
;; Execution time std-deviation : 1.560488 µs
;; Execution time lower quantile : 13.050947 µs ( 2.5%)
;; Execution time upper quantile : 17.956142 µs (97.5%)
;; Overhead used : 2.437790 ns
;; Found 6 outliers in 60 samples (10.0000 %)
;; low-severe 4 (6.6667 %)
;; low-mild 2 (3.3333 %)
;; Variance from outliers : 73.7509 % Variance is severely inflated by outliers
;; loop
;; Evaluation count : 6189540 in 60 samples of 103159 calls.
;; Execution time mean : 10.643343 µs
;; Execution time std-deviation : 1.496211 µs
;; Execution time lower quantile : 9.344473 µs ( 2.5%)
;; Execution time upper quantile : 15.186416 µs (97.5%)
;; Overhead used : 2.437790 ns
;; Found 7 outliers in 60 samples (11.6667 %)
;; low-severe 3 (5.0000 %)
;; low-mild 4 (6.6667 %)
;; Variance from outliers : 82.4182 % Variance is severely inflated by outliers
;; nil
;; user=>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment