summaryrefslogtreecommitdiff
path: root/bench
diff options
context:
space:
mode:
Diffstat (limited to 'bench')
-rw-r--r--bench/ruuter/bench.cljc58
1 files changed, 41 insertions, 17 deletions
diff --git a/bench/ruuter/bench.cljc b/bench/ruuter/bench.cljc
index 0048d13..71a02eb 100644
--- a/bench/ruuter/bench.cljc
+++ b/bench/ruuter/bench.cljc
@@ -1,25 +1,49 @@
(ns ruuter.bench
(:require [ruuter.core :as ruuter]))
-;; ── Benchmark Harness ──────────────────────────────────────────────────
-;; Cross-platform (JVM, ClojureScript/Node.js, Babashka).
+;; -- Benchmark Harness ---------------------------------------------------
+;; Cross-platform (JVM, ClojureScript/Node.js, Babashka, Jank).
+
+#?(:jank
+ (cpp/raw "#include <chrono>
+
+int64_t now_ns()
+{
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(
+ std::chrono::high_resolution_clock::now().time_since_epoch()
+ ).count();
+}
+"))
(defn- now-ns
"Returns the current time in nanoseconds."
[]
#?(:cljs (* (.now js/performance) 1e6)
- :clj (System/nanoTime)))
+ :jank (cpp/now_ns)
+ :default (System/nanoTime)))
+
+(defn- ->long
+ "Coerces a number to a long integer, cross-platform.
+ Uses `int` on Jank since `long` is not yet implemented."
+ [n]
+ #?(:jank (int n)
+ :default (long n)))
+
+(defn- ->double
+ "Coerces a number to a double, cross-platform."
+ [n]
+ (double n))
(defn- bench
"Run `f` for `warmup-ms` to warm up, then run it for `measure-ms` and
return {:ops n, :elapsed-ms ms, :ops-per-sec ops/s, :ns-per-op ns}."
[f & {:keys [warmup-ms measure-ms] :or {warmup-ms 2000 measure-ms 5000}}]
;; warmup
- (let [warmup-end (+ (now-ns) (* warmup-ms 1e6))]
+ (let [warmup-end (+ (now-ns) (->long (* warmup-ms 1e6)))]
(while (< (now-ns) warmup-end) (f)))
;; measure
(let [start (now-ns)
- deadline (+ start (* measure-ms 1e6))
+ deadline (+ start (->long (* measure-ms 1e6)))
total-ops (loop [cnt 0]
(f)
(let [cnt' (inc cnt)]
@@ -27,23 +51,23 @@
(recur cnt')
cnt')))
elapsed-ns (- (now-ns) start)
- elapsed-ms (/ elapsed-ns 1e6)
- ops-per-sec (long (/ (* total-ops 1e9) elapsed-ns))
- ns-per-op (long (/ elapsed-ns total-ops))]
+ elapsed-ms (/ (->double elapsed-ns) 1e6)
+ ops-per-sec (->long (/ (* (->double total-ops) 1e9) (->double elapsed-ns)))
+ ns-per-op (->long (/ (->double elapsed-ns) (->double total-ops)))]
{:ops total-ops
- :elapsed-ms (long elapsed-ms)
+ :elapsed-ms (->long elapsed-ms)
:ops-per-sec ops-per-sec
:ns-per-op ns-per-op}))
(defn- format-number
"Formats an integer with comma grouping, cross-platform."
[n]
- #?(:cljs (let [s (str n)
- reversed-digits (reverse s)
- groups (map #(apply str (reverse %))
- (partition-all 3 reversed-digits))]
- (string/join "," (reverse groups)))
- :clj (format "%,d" n)))
+ #?(:clj (format "%,d" n)
+ :default (let [s (str n)
+ reversed-digits (reverse s)
+ groups (map #(apply str (reverse %))
+ (partition-all 3 reversed-digits))]
+ (apply str (interpose "," (reverse groups))))))
(defn- format-result [label {:keys [ops-per-sec ns-per-op]}]
(let [ops-str (format-number ops-per-sec)
@@ -54,7 +78,7 @@
" | " (apply str (repeat (max 0 (- 13 (count ns-str))) " ")) ns-str
" |")))
-;; ── Route Definitions ──────────────────────────────────────────────────
+;; -- Route Definitions ---------------------------------------------------
(def small-routes
"5 routes — typical small app."
@@ -85,7 +109,7 @@
(def medium-routes (generate-routes 50))
(def large-routes (generate-routes 200))
-;; ── Benchmark Scenarios ────────────────────────────────────────────────
+;; -- Benchmark Scenarios -------------------------------------------------
(defn run-benchmarks []
(println "\nRunning benchmarks (2s warmup + 5s measure each)...\n")