Last active
December 19, 2015 03:29
-
-
Save fsodomka/5890711 to your computer and use it in GitHub Desktop.
Helper functions for timing expressions and examples of use.
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
;; Copyright (c) Frantisek Sodomka | |
;; Distributed under the Eclipse Public License, the same as Clojure. | |
(defmacro timings [n & exprs] | |
`(if (= ~@exprs) | |
~(vec (for [expr exprs] | |
`(let [start# (System/nanoTime) | |
ret# (dotimes [~'_ ~n] ~expr) | |
end# (System/nanoTime)] | |
{:expr '~expr | |
:time (/ (- end# start#) 1e6)}))) | |
(throw (Exception. "Results of expressions are not equal")))) | |
;; Reporting | |
(defn round [n x] | |
(let [p (Math/pow 10.0 n)] | |
(/ (Math/round (* x p)) p))) | |
(defn add-perc [tms] | |
(let [mx (apply max (map :time tms))] | |
(map #(assoc % :perc (round 2 (* 100 (/ (:time %) mx)))) tms))) | |
(defn add-ratio [tms] | |
(let [mn (apply min (map :time tms))] | |
(map #(assoc % :ratio (round 2 (/ (:time %) mn))) tms))) | |
(defn report [values] | |
(clojure.pprint/print-table | |
[:expr :time :ratio :perc] | |
(sort-by :time | |
(add-perc (add-ratio values))))) | |
;; Examples - arithmetic | |
(report (timings 1e7 (+ 1 2 3 4) (+ 1 (+ 2 (+ 3 4))))) | |
; | :expr | :time | :ratio | :perc | | |
; |---------------------+-----------+--------+-------| | |
; | (+ 1 2 3 4) | 55.985886 | 1.0 | 99.92 | | |
; | (+ 1 (+ 2 (+ 3 4))) | 56.030864 | 1.0 | 100.0 | | |
(report (let [x 1 y 42] (timings 1e7 (= x y) (== x y)))) | |
; | :expr | :time | :ratio | :perc | | |
; |----------+-----------+--------+-------| | |
; | (== x y) | 54.037595 | 1.0 | 99.65 | | |
; | (= x y) | 54.227842 | 1.0 | 100.0 | | |
;; Examples - vectors | |
; Destructuring is better! | |
(report | |
(let [v [1 2 3]] | |
(timings 1e6 | |
(let [[a b c] v] | |
(vector a b c)) | |
(let [a (v 0) b (v 1) c (v 2)] | |
(vector a b c))))) | |
; | :expr | :time | :ratio | :perc | | |
; |------------------------------------------------+------------+--------+-------| | |
; | (let [[a b c] v] (vector a b c)) | 183.800175 | 1.0 | 86.26 | | |
; | (let [a (v 0) b (v 1) c (v 2)] (vector a b c)) | 213.070376 | 1.16 | 100.0 | | |
; Don't call 'first' on vectors | |
(report | |
(let [v (vec (range 1000))] | |
(timings 1e6 | |
(v 0) | |
(nth v 0) | |
(first v)))) | |
; | :expr | :time | :ratio | :perc | | |
; |-----------+------------+--------+-------| | |
; | (nth v 0) | 39.413389 | 1.0 | 24.19 | | |
; | (v 0) | 44.969123 | 1.14 | 27.6 | | |
; | (first v) | 162.919031 | 4.13 | 100.0 | | |
; LazySeq to PersistentVector conversion - into [] is twice as fast as vec | |
(report | |
(let [lst (range 1e5)] | |
(timings 10 | |
(vec lst) | |
(apply vector lst) | |
(into [] lst) | |
(reduce conj [] lst)))) | |
; | :expr | :time | :ratio | :perc | | |
; |----------------------+------------+--------+-------| | |
; | (into [] lst) | 73.725013 | 1.0 | 29.49 | | |
; | (vec lst) | 158.771017 | 2.15 | 63.5 | | |
; | (apply vector lst) | 159.247613 | 2.16 | 63.69 | | |
; | (reduce conj [] lst) | 250.029263 | 3.39 | 100.0 | | |
; PersistentList to PersistentVector conversion - vec is twice as fast as into [] | |
(report | |
(let [lst (apply list (range 1e5))] | |
(timings 10 | |
(vec lst) | |
(apply vector lst) | |
(into [] lst) | |
(reduce conj [] lst)))) | |
; | :expr | :time | :ratio | :perc | | |
; |----------------------+------------+--------+-------| | |
; | (vec lst) | 84.877827 | 1.0 | 26.53 | | |
; | (apply vector lst) | 91.701319 | 1.08 | 28.66 | | |
; | (into [] lst) | 177.553292 | 2.09 | 55.49 | | |
; | (reduce conj [] lst) | 319.953514 | 3.77 | 100.0 | | |
;; ArrayList vs. PersistentVector - verifying results that vector is about 15% faster | |
;; https://news.ycombinator.com/item?id=5944438 | |
(report | |
(let [v (vec (range 100000)) | |
a (java.util.ArrayList. (range 100000))] | |
(timings 100 | |
(reduce + v) | |
(reduce + a)))) | |
; | :expr | :time | :ratio | :perc | | |
; |--------------+-------------+--------+--------| | |
; | (reduce + v) | 883.458372 | 1.00 | 87.45 | | |
; | (reduce + a) | 1010.263595 | 1.14 | 100.00 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment