lumbda/tests/bench-3way.sh
russell@unturf.com f7352b51b0 rename: uncommonlisp -> lumbda throughout the repo
Historical internal name "uncommonlisp" retired in favor of the
public name "lumbda" ahead of lumbda.com going live. Scope of
this commit:

Source files renamed:
  uncommonlisp.py                     -> lumbda.py
  asm/uncommonlisp.s                  -> asm/lumbda.s
  c/uncommonlisp.h                    -> c/lumbda.h
  whitepaper/uncommonlisp-whitepaper  -> whitepaper/lumbda-whitepaper (.rst + .pdf)

Binaries renamed (tracked ones; c/ was always gitignored):
  asm/uncommonlisp, asm/uncommonlisp-gc, asm/uncommonlisp.o,
  asm/uncommonlisp-gc.o                -> asm/lumbda(-gc)(.o)
  c/.gitignore                          -> ignores lumbda

Internal string updates (sed pass ordered longest-first):
  asm/uncommonlisp -> asm/lumbda
  c/uncommonlisp   -> c/lumbda
  uncommonlisp.py  -> lumbda.py
  UNCOMMONLISP_BIN -> LUMBDA_BIN (asm/test.sh env var)
  "uncommonlisp> " -> "lumbda> " (asm REPL prompt baked into binary)
  UNCOMMONLISP     -> LUMBDA (macros, comments)
  uncommonlisp     -> lumbda (prose)

Binary portal magic updated:
  "ULPORTAL" -> "LUMBDAB1"   # "Lumbda Binary v1"
Old portal files are not backward-compatible — this is a deliberate
break since it's the rename moment. S-expression portals already
carry their own ";; lumbda-portal v1" header and remain cleanly
versioned.

WHITEPAPER.pdf / WHITEPAPER.rst symlinks repointed to the renamed
files. Makefile's whitepaper target targets lumbda-whitepaper.pdf.

Not changed (intentional, separate phases):
  - Filesystem directory /home/fox/git/uncommonlisp itself
    (fox renames locally and the gitlab repo URL in a follow-up)
  - tests.py hardcoded cwd=/home/fox/git/uncommonlisp
    (matches the current on-disk location; will flip when the
    directory rename ships)
  - Git history (immutable; old commits still say uncommonlisp,
    which is correct — that's what they were)

Verified:
  137 asm no-GC + 137 asm GC + 571 Python + 83 C + 189 shared
  functional tests all pass under the new names.
  bench-gc-http (2000 req): all 4 cells behave as expected
  (cells 1/2 flat, 3 leaks, 4 bounded at 1 chunk).
  Python REPL, C REPL, asm REPL all start cleanly.
2026-04-19 10:20:11 -04:00

77 lines
3.1 KiB
Bash
Executable file

#!/bin/bash
# bench-3way.sh — head-to-head: Python --fast vs C --fast vs asm
#
# Runs sum-to(100k), sum-to(1M), ackermann(3,8) under each impl's
# high-performance mode and prints a comparison table. Drives the
# numbers in §6.4 of the whitepaper.
#
# Usage: bash tests/bench-3way.sh
# Safety: no backgrounded servers, no sockets, no stray processes.
# Each run is a single short-lived foreground process.
set -e
cd "$(dirname "$0")/.."
ulimit -v 2097152 # 2 GB virt cap (bytecode VM can use more than asm)
cat > /tmp/bench-3way.lsp <<'EOF'
(define (sum-to n)
(let loop ((i 0) (acc 0))
(if (= i n) acc (loop (+ i 1) (+ acc i)))))
(define (ack m n)
(cond ((= m 0) (+ n 1))
((= n 0) (ack (- m 1) 1))
(else (ack (- m 1) (ack m (- n 1))))))
(define t0 (current-time-ms)) (sum-to 100000) (define t1 (current-time-ms))
(define t2 (current-time-ms)) (sum-to 1000000) (define t3 (current-time-ms))
(define t4 (current-time-ms)) (ack 3 8) (define t5 (current-time-ms))
(display "sum-to(100k): ") (display (- t1 t0)) (newline)
(display "sum-to(1M): ") (display (- t3 t2)) (newline)
(display "ack(3,8): ") (display (- t5 t4)) (newline)
EOF
echo "═══════════════════════════════════════════════════════════════════"
echo "Three implementations head-to-head (best of 2 runs, ms)"
echo " Python --fast (bytecode VM) | C --fast (bytecode VM) | asm (tree-walker)"
echo "═══════════════════════════════════════════════════════════════════"
echo
best_of_two() {
# Run twice, take the smaller time per metric. Each run prints
# sum-to(100k): N
# sum-to(1M): N
# ack(3,8): N
# (asm additionally prints the results themselves first; we grep
# only the metric lines.)
local cmd="$1"
local r1 r2
r1=$(mktemp); r2=$(mktemp)
eval "timeout 60 $cmd" 2>&1 | grep -E "sum-to|ack" > "$r1"
eval "timeout 60 $cmd" 2>&1 | grep -E "sum-to|ack" > "$r2"
paste "$r1" "$r2" | awk -F'\t' '{
# Each side is "label: N". Parse each label/number.
n1 = $1; n2 = $2
sub(/.*: */, "", n1); n1 += 0
sub(/.*: */, "", n2); n2 += 0
label = $1; sub(/:.*/, ":", label)
min = (n1 < n2) ? n1 : n2
printf " %-16s %6d ms\n", label, min
}'
rm -f "$r1" "$r2"
}
echo "── Python (--fast) ──"
best_of_two "python3 lumbda.py --fast /tmp/bench-3way.lsp"
echo
echo "── C (--fast) ──"
best_of_two "c/lumbda --fast /tmp/bench-3way.lsp"
echo
echo "── asm ──"
best_of_two "asm/lumbda < /tmp/bench-3way.lsp"
echo
rm -f /tmp/bench-3way.lsp
echo "═══════════════════════════════════════════════════════════════════"
echo "Hardware: $(grep -m1 'model name' /proc/cpuinfo | cut -d: -f2 | xargs)"
echo "Kernel: $(uname -r)"