bench/run.sh was Janet-era: it invoked a 'jolt' binary and set JOLT_DIRECT_LINK/JOLT_WHOLE_PROGRAM, none of which exist on Chez, where 'joltc run -m' runs fully unoptimized (direct-link and inline default off). So the suite was measuring jolt's unoptimized path. run.sh now compiles each benchmark to an optimized AOT binary (joltc build --direct-link --opt) and times it against JVM Clojure on the same portable source, auto-detecting the Chez kernel dev files like build-smoke.sh. Adds bench/deps.edn so joltc resolves the namespaces, NO_JVM to skip the reference. mandelbrot.clj dropped its jolt.png require so the JVM reference can run it; the picture demo moved to mandelbrot_png.clj (jolt-only). README scorecard refreshed with current Chez numbers and the two-regime read (compute ~8-10x substrate floor; dispatch/alloc ~120-330x architectural gaps the passes don't touch). Stale 'jolt -m' header lines point at bench/run.sh.
70 lines
3 KiB
Bash
Executable file
70 lines
3 KiB
Bash
Executable file
#!/bin/sh
|
|
# Run the jolt benchmark suite against JVM Clojure and print a jolt/JVM scorecard.
|
|
#
|
|
# jolt's optimizing passes (direct-linking, inlining, scalar-replace, whole-program
|
|
# inference) fire only in an AOT BUILD — `joltc run -m` is unoptimized — so each
|
|
# benchmark is compiled to an optimized standalone binary and timed. JVM Clojure
|
|
# runs the same portable source for the absolute reference. Each benchmark prints
|
|
# `runs: [...]` and `mean: N ms`; the table shows the means and the jolt/JVM ratio.
|
|
#
|
|
# bench/run.sh # full suite + JVM scorecard
|
|
# bench/run.sh fib # one benchmark, default size
|
|
# bench/run.sh fib 32 # one benchmark, custom size
|
|
# NO_JVM=1 bench/run.sh # jolt only (skip the JVM reference)
|
|
#
|
|
# Building needs Chez's kernel dev files (libkernel.a + scheme.h) and a C compiler,
|
|
# the same as `jolt build`; set JOLT_CHEZ_CSV to override the detected csv dir.
|
|
set -e
|
|
cd "$(dirname "$0")"
|
|
root="$(cd .. && pwd)"
|
|
joltc="$root/bin/joltc"
|
|
export JOLT_PWD="$PWD"
|
|
|
|
# Locate Chez's kernel dev files for the optimized build (as build-smoke.sh does).
|
|
csv="$JOLT_CHEZ_CSV"
|
|
if [ -z "$csv" ]; then
|
|
chez_bin="$(command -v chez || command -v scheme || command -v petite || true)"
|
|
if [ -n "$chez_bin" ]; then
|
|
base="$(cd "$(dirname "$chez_bin")/.." 2>/dev/null && pwd)"
|
|
for d in "$base"/lib/csv*/*/; do
|
|
[ -f "${d}libkernel.a" ] && csv="${d%/}" && break
|
|
done
|
|
fi
|
|
fi
|
|
if [ -z "$csv" ] || [ ! -f "$csv/libkernel.a" ] || [ ! -f "$csv/scheme.h" ] || ! command -v cc >/dev/null 2>&1; then
|
|
echo "error: the optimized build needs Chez kernel dev files (libkernel.a + scheme.h) and cc." >&2
|
|
echo " set JOLT_CHEZ_CSV to the csv dir, e.g. \$(brew --prefix chezscheme)/lib/csv*/<machine>." >&2
|
|
exit 1
|
|
fi
|
|
export JOLT_CHEZ_CSV="$csv"
|
|
|
|
bindir="$(mktemp -d)"
|
|
trap 'rm -rf "$bindir"' EXIT
|
|
|
|
# name:default-arg, each sized to run in a few seconds. Axes: see README.md.
|
|
BENCHES="fib:30 mandelbrot:200 collections:30000 mono-dispatch:2000 dispatch:2000 binary-trees:14"
|
|
|
|
run_one() {
|
|
ns="${1%%:*}"; arg="${2:-${1##*:}}"
|
|
if ! "$joltc" build -m "$ns" -o "$bindir/$ns" --direct-link --opt >/dev/null 2>&1; then
|
|
printf '%-16s jolt build FAILED\n' "$ns"; return
|
|
fi
|
|
jmean=$("$bindir/$ns" "$arg" 2>/dev/null | awk '/^mean:/{print $2}')
|
|
if [ -z "$NO_JVM" ]; then
|
|
vmean=$(clojure -Sdeps '{:paths ["."]}' -M -m "$ns" "$arg" 2>/dev/null | awk '/^mean:/{print $2}')
|
|
ratio=$(awk "BEGIN{ if (\"$vmean\"+0>0 && \"$jmean\"+0>0) printf \"%.1fx\", (\"$jmean\"+0)/(\"$vmean\"+0); else printf \"-\" }")
|
|
printf '%-16s jolt %9s ms jvm %8s ms %s\n' "$ns" "${jmean:--}" "${vmean:--}" "$ratio"
|
|
else
|
|
printf '%-16s jolt %9s ms\n' "$ns" "${jmean:--}"
|
|
fi
|
|
}
|
|
|
|
if [ -n "$1" ]; then
|
|
spec=""
|
|
for s in $BENCHES; do [ "${s%%:*}" = "$1" ] && spec="$s"; done
|
|
[ -n "$spec" ] || { echo "unknown benchmark: $1 (have: ${BENCHES})" >&2; exit 1; }
|
|
run_one "$spec" "$2"
|
|
else
|
|
echo "jolt benchmark suite — optimized AOT binaries${NO_JVM:+ }${NO_JVM:-, vs JVM Clojure}"
|
|
for spec in $BENCHES; do run_one "$spec"; done
|
|
fi
|