From d7cfafd3a9467a081751fb1ee3d5cd1fa32232ef Mon Sep 17 00:00:00 2001 From: Yogthos Date: Sat, 20 Jun 2026 14:30:36 -0400 Subject: [PATCH] Chez Phase 4: perf probe (test/chez/bench-chez.ss) Mirrors test/bench/core-bench.janet's 8 compute programs + methodology (load the runtime once, time compile+run of each, min of N) so the zero-Janet Chez path is comparable to the Janet compile path. Result: Chez is 3-33x faster than Janet across the set (~320ms vs ~5000ms total, ~15x), biggest on seq/map/reduce, smallest on fib (3.2x). So deleting Janet is a perf win, which satisfies the "perf confirmed" precondition Phase 5 gates on. Chez is ~2-28x slower than JVM Clojure, expected and not the bar (and the Janet-only optimizing modes haven't been tried on Chez). jolt-cf1q.5 --- test/chez/bench-chez.ss | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test/chez/bench-chez.ss diff --git a/test/chez/bench-chez.ss b/test/chez/bench-chez.ss new file mode 100644 index 0000000..488dc05 --- /dev/null +++ b/test/chez/bench-chez.ss @@ -0,0 +1,42 @@ +;; bench-chez.ss (jolt-cf1q.5) — Phase 4 perf probe for the zero-Janet Chez path. +;; +;; Mirrors test/bench/core-bench.janet's programs and methodology (load the runtime +;; ONCE, then time compile+run of each program, min of N) so the Chez compute path +;; (analyze->Scheme->Chez eval) is comparable to the Janet compile path. Run: +;; chez --script test/chez/bench-chez.ss +(import (chezscheme)) +(load "host/chez/rt.ss") +(set-chez-ns! "clojure.core") +(load "host/chez/seed/prelude.ss") +(load "host/chez/post-prelude.ss") +(set-chez-ns! "user") +(load "host/chez/host-contract.ss") +(load "host/chez/seed/image.ss") +(load "host/chez/compile-eval.ss") + +(define runs 5) +(define benches + (list + (cons "fib" "(defn fib [n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) (fib 28)") + (cons "seq-pipe" "(loop [i 0 a 0] (if (< i 300) (recur (inc i) (+ a (reduce + 0 (map inc (filter even? (range 200)))))) a))") + (cons "reduce" "(loop [i 0 a 0] (if (< i 2000) (recur (inc i) (+ a (reduce + 0 (range 500)))) a))") + (cons "into-vec" "(loop [i 0 a 0] (if (< i 1000) (recur (inc i) (+ a (count (into [] (map inc (range 100)))))) a))") + (cons "map-build" "(loop [i 0 a 0] (if (< i 2000) (recur (inc i) (+ a (count (reduce (fn [m k] (assoc m k k)) {} (range 50))))) a))") + (cons "map-read" "(let [m (zipmap (range 100) (range 100))] (loop [i 0 a 0] (if (< i 5000) (recur (inc i) (+ a (get m (mod i 100) 0))) a)))") + (cons "str-join" "(loop [i 0 a 0] (if (< i 1000) (recur (inc i) (+ a (count (apply str (map str (range 100)))))) a))") + (cons "hof" "(loop [i 0 a 0] (if (< i 2000) (recur (inc i) (+ a (reduce + 0 (map (comp inc inc) (range 200))))) a))"))) + +(define (now-ms) + (let ((t (current-time 'time-monotonic))) + (+ (* 1000.0 (time-second t)) (/ (time-nanosecond t) 1000000.0)))) + +(for-each + (lambda (b) + (let ((name (car b)) (src (string-append "(do " (cdr b) ")"))) + (let loop ((i 0) (best +inf.0)) + (if (>= i runs) + (printf "~a\t~a ms\n" name (/ (round (* 100 best)) 100.0)) + (let ((t0 (now-ms))) + (jolt-compile-eval src "user") + (loop (+ i 1) (min best (- (now-ms) t0)))))))) + benches)