|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# Run all tsb (TypeScript) and pandas (Python) benchmarks and collect results. |
| 4 | +# |
| 5 | +# Usage: ./benchmarks/run_benchmarks.sh |
| 6 | +# |
| 7 | +# Outputs: benchmarks/results.json with all benchmark results |
| 8 | +# |
| 9 | +set -euo pipefail |
| 10 | + |
| 11 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 12 | +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" |
| 13 | + |
| 14 | +# Ensure Python and pandas are available |
| 15 | +if ! command -v python3 &>/dev/null; then |
| 16 | + echo "ERROR: python3 is required but not found" >&2 |
| 17 | + exit 1 |
| 18 | +fi |
| 19 | + |
| 20 | +python3 -c "import pandas" 2>/dev/null || { |
| 21 | + echo "Installing pandas..." |
| 22 | + pip3 install pandas --quiet |
| 23 | +} |
| 24 | + |
| 25 | +# Ensure Bun is available |
| 26 | +if ! command -v bun &>/dev/null; then |
| 27 | + echo "ERROR: bun is required but not found" >&2 |
| 28 | + exit 1 |
| 29 | +fi |
| 30 | + |
| 31 | +# Collect results |
| 32 | +results='{"benchmarks": [], "timestamp": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"}' |
| 33 | + |
| 34 | +echo "=== Running Performance Benchmarks ===" |
| 35 | +echo "" |
| 36 | + |
| 37 | +# Find all TypeScript benchmark files |
| 38 | +for ts_bench in "$SCRIPT_DIR"/tsb/bench_*.ts; do |
| 39 | + [ -f "$ts_bench" ] || continue |
| 40 | + bench_name=$(basename "$ts_bench" .ts | sed 's/^bench_//') |
| 41 | + |
| 42 | + # Check for matching Python benchmark |
| 43 | + py_bench="$SCRIPT_DIR/pandas/bench_${bench_name}.py" |
| 44 | + if [ ! -f "$py_bench" ]; then |
| 45 | + echo "SKIP: $bench_name (no matching Python benchmark)" |
| 46 | + continue |
| 47 | + fi |
| 48 | + |
| 49 | + echo "--- Benchmarking: $bench_name ---" |
| 50 | + |
| 51 | + # Run TypeScript benchmark |
| 52 | + echo " Running tsb (TypeScript)..." |
| 53 | + ts_result=$(cd "$REPO_ROOT" && bun run "$ts_bench" 2>/dev/null) || { |
| 54 | + echo " ERROR: TypeScript benchmark failed" |
| 55 | + continue |
| 56 | + } |
| 57 | + echo " tsb result: $ts_result" |
| 58 | + |
| 59 | + # Run Python benchmark |
| 60 | + echo " Running pandas (Python)..." |
| 61 | + py_result=$(cd "$REPO_ROOT" && python3 "$py_bench" 2>/dev/null) || { |
| 62 | + echo " ERROR: Python benchmark failed" |
| 63 | + continue |
| 64 | + } |
| 65 | + echo " pandas result: $py_result" |
| 66 | + |
| 67 | + # Extract mean_ms from both |
| 68 | + ts_mean=$(echo "$ts_result" | python3 -c "import sys, json; print(json.load(sys.stdin)['mean_ms'])") |
| 69 | + py_mean=$(echo "$py_result" | python3 -c "import sys, json; print(json.load(sys.stdin)['mean_ms'])") |
| 70 | + |
| 71 | + # Calculate ratio (tsb / pandas) — < 1.0 means tsb is faster |
| 72 | + ratio=$(python3 -c "print(round($ts_mean / $py_mean if $py_mean > 0 else 0, 3))") |
| 73 | + |
| 74 | + echo " Ratio (tsb/pandas): ${ratio}x" |
| 75 | + echo "" |
| 76 | + |
| 77 | + # Add to results JSON |
| 78 | + results=$(echo "$results" | python3 -c " |
| 79 | +import sys, json |
| 80 | +data = json.load(sys.stdin) |
| 81 | +data['benchmarks'].append({ |
| 82 | + 'function': '$bench_name', |
| 83 | + 'tsb': $ts_result, |
| 84 | + 'pandas': $py_result, |
| 85 | + 'ratio': $ratio |
| 86 | +}) |
| 87 | +print(json.dumps(data, indent=2)) |
| 88 | +") |
| 89 | +done |
| 90 | + |
| 91 | +# Write results |
| 92 | +echo "$results" > "$SCRIPT_DIR/results.json" |
| 93 | +echo "=== Results written to benchmarks/results.json ===" |
| 94 | +echo "" |
| 95 | + |
| 96 | +# Summary |
| 97 | +echo "=== Summary ===" |
| 98 | +echo "$results" | python3 -c " |
| 99 | +import sys, json |
| 100 | +data = json.load(sys.stdin) |
| 101 | +benchmarks = data.get('benchmarks', []) |
| 102 | +if not benchmarks: |
| 103 | + print('No benchmarks found.') |
| 104 | +else: |
| 105 | + print(f'Functions benchmarked: {len(benchmarks)}') |
| 106 | + for b in benchmarks: |
| 107 | + fn = b['function'] |
| 108 | + ts = b['tsb']['mean_ms'] |
| 109 | + py = b['pandas']['mean_ms'] |
| 110 | + ratio = b['ratio'] |
| 111 | + faster = 'tsb' if ratio < 1 else 'pandas' |
| 112 | + print(f' {fn}: tsb={ts}ms, pandas={py}ms, ratio={ratio}x ({faster} is faster)') |
| 113 | +" |
0 commit comments