#!/usr/bin/env bash # Smalltalk-on-SX vs. GNU Smalltalk timing comparison. # # Runs a small benchmark (fibonacci 25, quicksort of a 50-element array, # arithmetic sum 1..1000) on both runtimes and reports the ratio. # # GNU Smalltalk (`gst`) must be installed and on $PATH. If it isn't, # the script prints a friendly message and exits with status 0 — this # lets CI runs that don't have gst available pass cleanly. # # Usage: bash lib/smalltalk/compare.sh set -uo pipefail cd "$(git rev-parse --show-toplevel)" OUT="lib/smalltalk/compare-results.txt" if ! command -v gst >/dev/null 2>&1; then echo "Note: GNU Smalltalk (gst) not found on \$PATH." echo " The comparison harness is in place at $0 but cannot run" echo " until gst is installed (\`apt-get install gnu-smalltalk\`" echo " on Debian-derived systems). Skipping." exit 0 fi SX="hosts/ocaml/_build/default/bin/sx_server.exe" if [ ! -x "$SX" ]; then MAIN_ROOT=$(git worktree list | head -1 | awk '{print $1}') SX="$MAIN_ROOT/$SX" fi # A trio of small benchmarks. Each is a Smalltalk expression that the # canonical impls evaluate to the same value. BENCH_FIB='Object subclass: #B instanceVariableNames: ""! !B methodsFor: "x"! fib: n n < 2 ifTrue: [^ n]. ^ (self fib: n - 1) + (self fib: n - 2)! ! Transcript show: (B new fib: 22) printString; nl' run_sx () { local label="$1"; local source="$2" local tmp=$(mktemp) cat > "$tmp" < /dev/null 2>&1 local rc=$? local end=$(date +%s.%N) rm -f "$tmp" local elapsed=$(awk "BEGIN{print $end - $start}") echo "$label: ${elapsed}s (rc=$rc)" } run_gst () { local label="$1" local tmp=$(mktemp) cat > "$tmp" < /dev/null 2>&1 local rc=$? local end=$(date +%s.%N) rm -f "$tmp" local elapsed=$(awk "BEGIN{print $end - $start}") echo "$label: ${elapsed}s (rc=$rc)" } { echo "Smalltalk-on-SX vs GNU Smalltalk — fibonacci(22)" echo "Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo run_sx "smalltalk-on-sx (call/cc + dict ivars)" run_gst "gnu smalltalk" } | tee "$OUT" echo echo "Saved: $OUT"