(defmodule Bench (system-include "bench.h") (register get-time-elapsed (Fn [] Double)) (defn get-unit [n] (cond (> n 1000.0) (String.append (Double.str n) "µs") (> n 1000000.0) (String.append (Double.str (/ n 1000.0)) "ms") (> n 1000000000.0) (String.append (Double.str (/ n 1000000.0)) "s") (String.append (Double.str (/ n 1000000000.0)) "s"))) (defn print [title n] (let [unit (get-unit n)] (do (IO.println title) (IO.println &unit)))) (defn ns-iter-inner [f k] (let [start (get-time-elapsed)] (do (for [i 0 n] (f)) (Double.- (Bench.get-time-elapsed) before)))) (defn dbl-cmp [a b] (Double.- a b)) (defn winsorize [samples pct] (let [tmp (Array.sort samples dbl-cmp) ; and now? )) (defn bench [f] (let [ns (ns-iter-inner f 1) ns-target-total 1000000.0 n (Double./ ns-target-total (if (> 1 ns) 1 ns)) n (if (> 1 n) 1 n) total 0 samples []] (while (< total 3000000000) (let [loop-start (get-time-elapsed)] (do (for [i 0 50] (set! &samples &(Array.push-back (Double./ (ns-iter-inner f n) n)))) ; and now? )))))) (defmacro benchn [n form] (list 'let ['before (Bench.get-time-elapsed) 'times []] (list 'do (list 'for ['i 0 n] (list 'let ['before-once (Bench.get-time-elapsed)] (list 'do form (list 'set! × (Array.push-back (Array.copy ×) (Double.- (get-time-elapsed) before-once)))))) (list 'let ['total (Double.- (Bench.get-time-elapsed) before) 'per (list 'Double./ 'total (list 'Double.from-int n))] (do (Bench.print "Total time elapsed: " total) (Bench.print "Time elapsed per run (average): " per) (Bench.print "Best case: " (Statistics.min ×)) (Bench.print "Worst case: " (Statistics.max ×)) (Bench.print "Standard deviation: " (Statistics.stdev ×)))))))