Last active
December 18, 2018 13:16
-
-
Save xificurC/df079feb85bb118efd305764c8714cf5 to your computer and use it in GitHub Desktop.
Clojure specter benchmarks done with criterium benchmarking library
This file contains hidden or 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
Leiningen 2.8.1 on Java 1.8.0_181 OpenJDK 64-Bit Server VM | |
{:dependencies | |
([org.clojure/clojure "1.9.0"] [criterium/criterium "0.4.4"]), | |
:jvm-opts nil, | |
:eval-in nil} | |
Benchmark: get value in nested map | |
Mean(us) vs best Code | |
0.0220 1.00 (-> data (get :a) (get :b) (get :c)) | |
0.0332 1.51 (-> data :a :b :c) | |
0.0340 1.55 (-> data :a :b :c identity) | |
0.0359 1.63 (get-a-b-c data) | |
0.0612 2.78 (compiled-select-any p data) | |
0.0658 2.99 (select-any [(keypath :a) (keypath :b) (keypath :c)] data) | |
0.0660 3.00 (select-any [:a :b :c] data) | |
0.0730 3.32 (select-one [:a :b :c] data) | |
0.0845 3.84 (get-in data [:a :b :c]) | |
0.112 5.09 (select-any (keypath :a :b :c) data) | |
0.120 5.47 (select-one! [:a :b :c] data) | |
0.123 5.57 (select-first [:a :b :c] data) | |
0.129 5.87 (specter-dynamic-nested-get data :a :b :c) | |
******************************** | |
Benchmark: set value in nested map | |
Mean(us) vs best Code | |
0.177 1.00 (setval [:a :b :c] 1 data) | |
0.204 1.16 (assoc-in data [:a :b :c] 1) | |
******************************** | |
Benchmark: update value in nested map | |
Mean(us) vs best Code | |
0.206 1.00 (manual-transform data inc) | |
0.229 1.11 (transform [:a :b :c] inc data) | |
0.325 1.58 (update-in data [:a :b :c] inc) | |
******************************** | |
Benchmark: transform values of a list | |
Mean(us) vs best Code | |
0.648 1.00 (doall (sequence (map inc) data)) | |
0.807 1.24 (transform ALL inc data) | |
0.994 1.53 (reverse (into (quote ()) (map inc) data)) | |
******************************** | |
Benchmark: transform values of a small map | |
Mean(us) vs best Code | |
0.169 1.00 (transform MAP-VALS inc data) | |
0.189 1.12 (reduce-kv (fn [m k v] (assoc m k (inc v))) {} data) | |
0.204 1.21 (map-vals-map-iterable data inc) | |
0.215 1.27 (persistent! (reduce-kv (fn [m k v] (assoc! m k (inc v))) (transient {}) data)) | |
0.295 1.74 (map-vals-map-iterable-transient data inc) | |
0.297 1.76 (reduce-kv (fn [m k v] (assoc m k (inc v))) (empty data) data) | |
0.499 2.95 (into {} (map (fn [e] [(key e) (inc (val e))])) data) | |
0.911 5.39 (transform [ALL LAST] inc data) | |
1.23 7.25 (zipmap (keys data) (map inc (vals data))) | |
1.38 8.16 (into {} (for [[k v] data] [k (inc v)])) | |
1.39 8.23 (into {} (map (fn [e] [(key e) (inc (val e))]) data)) | |
******************************** | |
Benchmark: transform values of large map | |
Mean(us) vs best Code | |
185 1.00 (persistent! (reduce-kv (fn [m k v] (assoc! m k (inc v))) (transient clojure.lang.PersistentHashMap/EMPTY) data)) | |
190 1.03 (persistent! (reduce-kv (fn [m k v] (assoc! m k (inc v))) (transient {}) data)) | |
194 1.05 (transform MAP-VALS inc data) | |
229 1.24 (reduce-kv (fn [m k v] (assoc m k (inc v))) {} data) | |
248 1.34 (reduce-kv (fn [m k v] (assoc m k (inc v))) (empty data) data) | |
296 1.60 (into {} (map (fn [e] [(key e) (inc (val e))])) data) | |
322 1.74 (map-vals-map-iterable-transient data inc) | |
357 1.93 (map-vals-map-iterable data inc) | |
381 2.06 (transform [ALL LAST] inc data) | |
473 2.56 (into {} (for [[k v] data] [k (inc v)])) | |
479 2.59 (into {} (map (fn [e] [(key e) (inc (val e))]) data)) | |
534 2.88 (zipmap (keys data) (map inc (vals data))) | |
******************************** | |
Benchmark: first value of a size 10 vector | |
Mean(us) vs best Code | |
0.0415 1.00 (select-any ALL data) | |
0.0415 1.00 (select-first ALL data) | |
0.0562 1.35 (select-any FIRST data) | |
0.0705 1.70 (first data) | |
******************************** | |
Benchmark: map a function over a vector | |
Mean(us) vs best Code | |
0.214 1.00 (mapv inc data) | |
0.398 1.86 (into [] (map inc) data) | |
0.478 2.24 (transform ALL inc data) | |
0.664 3.11 (vec (map inc data)) | |
******************************** | |
Benchmark: filter a sequence | |
Mean(us) vs best Code | |
0.235 1.00 (filterv even? data) | |
0.364 1.55 (into [] (filter even?) data) | |
0.463 1.97 (select [ALL even?] data) | |
0.490 2.08 (doall (filter even? data)) | |
0.710 3.01 (select-any (filterer even?) data) | |
******************************** | |
Benchmark: even :a values from sequence of maps | |
Mean(us) vs best Code | |
0.385 1.00 (select [ALL :a even?] data) | |
0.532 1.38 (into [] xf data) | |
0.545 1.41 (into [] (comp (map :a) (filter even?)) data) | |
0.732 1.90 (->> data (mapv :a) (filter even?) doall) | |
******************************** | |
Benchmark: Append to a large vector | |
Mean(us) vs best Code | |
0.0397 1.00 (conj v 1) | |
0.0573 1.44 (reduce conj v [1]) | |
0.0684 1.72 (setval AFTER-ELEM 1 v) | |
0.196 4.94 (setval END [1] v) | |
******************************** | |
Benchmark: prepend to a vector | |
Mean(us) vs best Code | |
0.490 1.00 (into [0] data) | |
0.629 1.28 (vec (cons 0 data)) | |
0.641 1.31 (setval BEFORE-ELEM 0 data) | |
******************************** | |
Benchmark: update every value in a tree (represented with vectors) | |
Mean(us) vs best Code | |
1.90 1.00 (tree-value-transform (fn [e] (if (even? e) (inc e) e)) data) | |
2.78 1.46 (transform [TreeValuesProt even?] inc data) | |
3.25 1.71 (transform [TreeValues even?] inc data) | |
3.39 1.78 (transform [(walker number?) even?] inc data) | |
7.23 3.80 (walk/postwalk (fn [e] (if (and (number? e) (even? e)) (inc e) e)) data) | |
******************************** | |
Benchmark: transient comparison: building up vectors | |
Mean(us) vs best Code | |
19.1 1.00 (reduce (fn [v i] (conj! v i)) (transient []) toappend) | |
29.1 1.52 (setval END! toappend (transient [])) | |
43.0 2.25 (setval END toappend []) | |
45.2 2.37 (reduce (fn [v i] (conj v i)) [] toappend) | |
******************************** | |
Benchmark: transient comparison: building up vectors one at a time | |
Mean(us) vs best Code | |
21.3 1.00 (reduce (fn [v i] (conj! v i)) (transient []) toappend) | |
45.2 2.12 (reduce (fn [v i] (conj v i)) [] toappend) | |
105 4.95 (reduce (fn [v i] (setval END! [i] v)) (transient []) toappend) | |
240 11.3 (reduce (fn [v i] (setval END [i] v)) [] toappend) | |
******************************** | |
Benchmark: transient comparison: assoc'ing in vectors | |
Mean(us) vs best Code | |
0.0296 1.00 (assoc! tdata 600 0) | |
0.0740 2.50 (assoc data 600 0) | |
0.140 4.72 (setval (keypath! 600) 0 tdata2) | |
0.192 6.47 (setval (keypath 600) 0 data) | |
******************************** | |
Benchmark: transient comparison: assoc'ing in maps | |
Mean(us) vs best Code | |
0.0880 1.00 (assoc! tdata 600 0) | |
0.151 1.72 (assoc data 600 0) | |
0.262 2.98 (setval (keypath! 600) 0 tdata2) | |
0.346 3.93 (setval (keypath 600) 0 data) | |
******************************** | |
Benchmark: transient comparison: submap | |
Mean(us) vs best Code | |
1.50 1.00 (transform (submap! [600 700]) modify-submap tdata) | |
2.25 1.50 (transform (submap [600 700]) modify-submap data) | |
******************************** | |
Benchmark: set metadata | |
Mean(us) vs best Code | |
0.0735 1.00 (with-meta data meta-map) | |
0.164 2.23 (setval META meta-map data) | |
******************************** | |
Benchmark: get metadata | |
Mean(us) vs best Code | |
0.00959 1.00 (meta data) | |
0.0322 3.36 (select-any META data) | |
******************************** | |
Benchmark: vary metadata | |
Mean(us) vs best Code | |
0.293 1.00 (setval [META :y] 2 data) | |
0.572 1.95 (vary-meta data assoc :y 2) | |
******************************** | |
Benchmark: Traverse into a set | |
Mean(us) vs best Code | |
190 1.00 (set data) | |
199 1.05 (persistent! (reduce conj! (transient #{}) (traverse ALL data))) | |
200 1.05 (into #{} (traverse ALL data)) | |
232 1.22 (set (select ALL data)) | |
302 1.59 (reduce conj #{} (traverse ALL data)) | |
******************************** | |
Benchmark: multi-transform vs. consecutive transforms, one shared nav | |
Mean(us) vs best Code | |
1.40 1.00 (multi-transform [ALL (multi-path [even? (terminal mult-10)] [odd? (terminal dec)])] data) | |
2.04 1.46 (->> data (transform [ALL even?] mult-10) (transform [ALL odd?] dec)) | |
******************************** | |
Benchmark: multi-transform vs. consecutive transforms, three shared navs | |
Mean(us) vs best Code | |
5.24 1.00 (multi-transform [ALL ALL number? (multi-path [even? (terminal mult-10)] [odd? (terminal dec)])] data) | |
7.36 1.41 (->> data (transform [ALL ALL number? even?] mult-10) (transform [ALL ALL number? odd?] dec)) | |
******************************** | |
Benchmark: namespace qualify keys of a small map | |
Mean(us) vs best Code | |
0.379 1.00 (setval [MAP-KEYS NAMESPACE] (str *ns*) data) | |
0.578 1.53 (reduce-kv (fn [m k v] (assoc m (keyword (str *ns*) (name k)) v)) {} data) | |
1.24 3.27 (into {} (map (fn [[k v]] [(keyword (str *ns*) (name k)) v])) data) | |
******************************** | |
Benchmark: namespace qualify keys of a large map | |
Mean(us) vs best Code | |
321 1.00 (setval [MAP-KEYS NAMESPACE] (str *ns*) data) | |
488 1.52 (into {} (map (fn [[k v]] [(keyword (str *ns*) (name k)) v])) data) | |
508 1.58 (reduce-kv (fn [m k v] (assoc m (keyword (str *ns*) (name k)) v)) {} data) | |
******************************** | |
Benchmark: walker vs. clojure.walk version | |
Mean(us) vs best Code | |
8.49 1.00 (transform (walker number?) inc data) | |
13.3 1.56 (transform (walker-old number?) inc data) | |
******************************** | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment