bench-compile.sh raw

   1  #!/bin/bash
   2  # Benchmark: moxie (legacy) vs moxie-iskra (lattice) compilation
   3  # Measures wall time, output size, and match rate across the smesh corpus.
   4  # Run with RUNS=N to control iterations (default 5).
   5  # Run with DROP_CACHE=1 to drop filesystem caches between runs (needs sudo).
   6  set -e
   7  
   8  SMESH="${SMESH:-$HOME/s/smesh}"
   9  MOXIE="${MOXIE:-$HOME/s/moxie}"
  10  RUNS="${RUNS:-5}"
  11  DROP_CACHE="${DROP_CACHE:-0}"
  12  OUT="/tmp/bench-compile"
  13  
  14  export MOXIEROOT="$MOXIE"
  15  export GOWORK=off
  16  
  17  rm -rf "$OUT"
  18  mkdir -p "$OUT"
  19  
  20  median() {
  21      sort -n | awk '{a[NR]=$1} END {print a[int((NR+1)/2)]}'
  22  }
  23  
  24  drop_caches() {
  25      if [ "$DROP_CACHE" = "1" ]; then
  26          sync
  27          echo 3 | sudo tee /proc/sys/vm/drop_caches >/dev/null 2>&1 || true
  28      fi
  29  }
  30  
  31  run_timed() {
  32      local label="$1"; shift
  33      local times=""
  34      for i in $(seq 1 "$RUNS"); do
  35          drop_caches
  36          t0=$(date +%s%N)
  37          "$@" >/dev/null 2>/dev/null || true
  38          t1=$(date +%s%N)
  39          ms=$(( (t1 - t0) / 1000000 ))
  40          times="$times $ms"
  41      done
  42      med=$(echo "$times" | tr ' ' '\n' | grep -v '^$' | median)
  43      min=$(echo "$times" | tr ' ' '\n' | grep -v '^$' | sort -n | head -1)
  44      max=$(echo "$times" | tr ' ' '\n' | grep -v '^$' | sort -n | tail -1)
  45      printf "  %-45s  %6d ms  (min %d, max %d)\n" "$label" "$med" "$min" "$max"
  46  }
  47  
  48  echo "=== Benchmark: moxie vs moxie-iskra ==="
  49  echo "  smesh:      $SMESH"
  50  echo "  moxie:      $MOXIE"
  51  echo "  runs:       $RUNS"
  52  echo "  drop_cache: $DROP_CACHE"
  53  echo ""
  54  
  55  # --- Source stats ---
  56  webmx=$(find "$SMESH/web" -name '*.mx' -not -name '*_test.mx' | wc -l)
  57  weblines=$(find "$SMESH/web" -name '*.mx' -not -name '*_test.mx' -exec cat {} + | wc -l)
  58  nativemx=$(find "$SMESH" -maxdepth 1 -name '*.mx' -not -name '*_test.mx' | wc -l)
  59  nativemx=$((nativemx + $(find "$SMESH/pkg" -name '*.mx' -not -name '*_test.mx' 2>/dev/null | wc -l)))
  60  nativelines=$({ find "$SMESH" -maxdepth 1 -name '*.mx' -not -name '*_test.mx' -exec cat {} +; find "$SMESH/pkg" -name '*.mx' -not -name '*_test.mx' -exec cat {} +; } 2>/dev/null | wc -l)
  61  echo "Source corpus:"
  62  echo "  web frontend:   $webmx files, $weblines lines"
  63  echo "  native relay:   $nativemx files, $nativelines lines"
  64  echo ""
  65  
  66  # --- 1. Native relay ---
  67  echo "--- Native relay build ---"
  68  run_timed "moxie build (native relay)" \
  69      sh -c "cd $SMESH && moxie build -o $OUT/relay-moxie ."
  70  relayMoxie=$(stat -c%s "$OUT/relay-moxie" 2>/dev/null || echo 0)
  71  
  72  run_timed "moxie-iskra build (native relay)" \
  73      sh -c "cd $SMESH && moxie-iskra build -o $OUT/relay-iskra . 2>/dev/null"
  74  relayIskra=$(stat -c%s "$OUT/relay-iskra" 2>/dev/null || echo 0)
  75  
  76  printf "  moxie output:       %d bytes (%d KB)\n" "$relayMoxie" $((relayMoxie/1024))
  77  printf "  moxie-iskra output: %d bytes (%d KB)\n" "$relayIskra" $((relayIskra/1024))
  78  echo ""
  79  
  80  # --- 2. Web frontend: moxiejs (legacy JS transpiler) ---
  81  echo "--- Web frontend: moxiejs (JS output) ---"
  82  run_timed "moxiejs (web/app -> JS)" \
  83      sh -c "cd $SMESH && GOWORK=off moxiejs -runtime $MOXIE/jsruntime -o $OUT/js/ ./web/app/"
  84  jssize=$(find "$OUT/js" -name '*.mjs' -exec cat {} + 2>/dev/null | wc -c)
  85  jsgz=$(find "$OUT/js" -name '*.mjs' -exec cat {} + 2>/dev/null | gzip -c | wc -c)
  86  printf "  output: %d bytes (%d KB), gzipped: %d bytes (%d KB)\n" "$jssize" $((jssize/1024)) "$jsgz" $((jsgz/1024))
  87  echo ""
  88  
  89  # --- 3. Web frontend: moxie-iskra wasm32 ---
  90  echo "--- Web frontend: moxie-iskra (WASM output) ---"
  91  run_timed "moxie-iskra build -target wasm32 (web/app)" \
  92      sh -c "cd $SMESH && moxie-iskra build -target wasm32 -o $OUT/app.wasm web/app/ 2>/dev/null"
  93  wasmsize=$(stat -c%s "$OUT/app.wasm" 2>/dev/null || echo 0)
  94  wasmgz=$(gzip -c "$OUT/app.wasm" 2>/dev/null | wc -c)
  95  printf "  output: %d bytes (%d KB), gzipped: %d bytes (%d KB)\n" "$wasmsize" $((wasmsize/1024)) "$wasmgz" $((wasmgz/1024))
  96  
  97  # wasm-opt
  98  if command -v wasm-opt >/dev/null 2>&1; then
  99      wasm-opt -Oz --strip-debug "$OUT/app.wasm" -o "$OUT/app.opt.wasm" 2>/dev/null
 100      optsize=$(stat -c%s "$OUT/app.opt.wasm" 2>/dev/null || echo 0)
 101      optgz=$(gzip -c "$OUT/app.opt.wasm" 2>/dev/null | wc -c)
 102      printf "  optimized: %d bytes (%d KB), gzipped: %d bytes (%d KB)\n" "$optsize" $((optsize/1024)) "$optgz" $((optgz/1024))
 103  fi
 104  echo ""
 105  
 106  # --- 4. Size comparison ---
 107  echo "=== Size comparison ==="
 108  printf "  %-35s  %8s  %8s\n" "" "raw" "gzipped"
 109  relayMoxieGz=0
 110  relayIskraGz=0
 111  if [ -f "$OUT/relay-moxie" ]; then relayMoxieGz=$(gzip -c "$OUT/relay-moxie" | wc -c); fi
 112  if [ -f "$OUT/relay-iskra" ]; then relayIskraGz=$(gzip -c "$OUT/relay-iskra" | wc -c); fi
 113  printf "  %-35s  %7dK  %7dK\n" "native: moxie" $((relayMoxie/1024)) $((relayMoxieGz/1024))
 114  printf "  %-35s  %7dK  %7dK\n" "native: moxie-iskra" $((relayIskra/1024)) $((relayIskraGz/1024))
 115  printf "  %-35s  %7dK  %7dK\n" "web: moxiejs (JS)" $((jssize/1024)) $((jsgz/1024))
 116  printf "  %-35s  %7dK  %7dK\n" "web: moxie-iskra (WASM)" $((wasmsize/1024)) $((wasmgz/1024))
 117  if [ -f "$OUT/app.opt.wasm" ]; then
 118      printf "  %-35s  %7dK  %7dK\n" "web: moxie-iskra (WASM, -Oz)" $((optsize/1024)) $((optgz/1024))
 119  fi
 120  if [ "$jsgz" -gt 0 ] && [ "$optgz" -gt 0 ]; then
 121      ratio=$((jsgz * 100 / optgz))
 122      printf "\n  WASM (-Oz, gzipped) is %d.%dx smaller than JS (gzipped)\n" $((ratio/100)) $(( (ratio/10) % 10))
 123  fi
 124  echo ""
 125  
 126  rm -rf "$OUT"
 127  echo "done."
 128