Lambda Benchmark Results: 6 Suites × 6 Engines (Round 4)

March 19, 2026 · View on GitHub

Date: 2026-03-19
Platform: Apple Silicon MacBook Air (M4, aarch64), macOS
Lambda version: release build (8.4 MB, stripped, -O2)
Node.js: v22.13.0 (V8 JIT)
QuickJS: v2025-09-13 (interpreter)
Python: 3.13.3 (CPython)
Methodology: 3 runs per benchmark, median of self-reported execution time (excludes startup/JIT compilation overhead)


Engine Overview

EngineTypeDescription
MIR DirectJITLambda → MIR IR → native code (default compiler path)
C2MIRJITLambda → C source → MIR (legacy path via c2mir)
LambdaJSJITLambda's built-in JavaScript JIT
QuickJSInterpreterStandalone QuickJS JavaScript engine
Node.jsJITGoogle V8 JavaScript engine with optimizing JIT
PythonInterpreterCPython 3.13 reference interpreter

R7RS Benchmarks

Classic Scheme benchmark suite adapted for Lambda with type annotations. Tests recursive functions, numeric computation, and backtracking.

BenchmarkCategoryMIRC2MIRLambdaJSQuickJSNode.jsPythonMIR/NodeMIR/Py
fibrecursive2.52.10.99182.0221.23x0.11x
fibfprecursive3.73.51.0191.8232.11x0.16x
takrecursive0.150.160.102.90.802.20.19x0.07x
cpstakclosure0.300.340.225.71.004.50.30x0.07x
sumiterative0.271.894321.2380.23x0.007x
sumfpiterative0.0670.33143.80.872.80.08x0.02x
nqueensbacktrack6.76.66.89.71.83.53.72x1.90x
fftnumeric0.181.09.82.81.74.30.11x0.04x
mbrotnumeric0.590.7455181.8150.34x0.04x
ackrecursive9.89.88.1---141560.72x0.06x

Geometric mean MIR/Node.js: 0.44x — Lambda faster on 7/10 benchmarks Geometric mean MIR/Python: 0.07x — Lambda faster on 9/10 benchmarks


AWFY Benchmarks

Standard cross-language benchmark suite from Stefan Marr. Lambda implementations use procedural style; JS uses official AWFY source.

BenchmarkCategoryMIRC2MIRLambdaJSQuickJSNode.jsPythonMIR/NodeMIR/Py
sievemicro0.0520.0520.770.600.381.76s0.14x0.000x
permutemicro0.0640.068131.60.812.11s0.08x0.000x
queensmicro0.150.14111.10.641.14s0.23x0.000x
towersmicro0.220.11232.31.11.11s0.19x0.000x
bouncemicro0.190.14100.960.551.39s0.35x0.000x
listmicro0.0230.627.90.920.509760.05x0.000x
storagemicro0.190.326.22.70.641.27s0.30x0.000x
mandelbrotcompute325527988832---1.00x---
nbodycompute47842.06s1675.61358.38x0.35x
richardsmacro2532193.31s194481685.29x1.50x
jsonmacro1.52.1160122.87.10.54x0.21x
deltabluemacro647893511313685.07x0.94x
havlakmacro618239.66s4.09s922.11s0.66x0.03x
cdmacro22035811.66s1.06s37---5.94x---

Geometric mean MIR/Node.js: 0.62x — Lambda faster on 10/14 benchmarks Geometric mean MIR/Python: 0.00x — Lambda faster on 11/12 benchmarks


BENG Benchmarks

Subset of the Computer Language Benchmarks Game. Tests diverse real-world computation: GC stress, regex, FASTA I/O, numeric precision, permutations.

BenchmarkCategoryMIRC2MIRLambdaJSQuickJSNode.jsPythonMIR/NodeMIR/Py
binarytreesallocation7.37.7114284.1101.76x0.70x
fannkuchpermutation0.761.11.67.34.15.10.18x0.15x
fastageneration1.10.843.9116.22.00.18x0.55x
knucleotidehashing2.93.80.088---5.03.90.58x0.74x
mandelbrotnumeric1422382.85s698161.37s9.13x0.10x
nbodynumeric47851.75s1558.11725.84x0.27x
pidigitsbignum0.460.300.0830.162.00.100.23x4.53x
regexreduxregex1.21.40.095---2.51.50.50x0.85x
revcompstring1.81.80.002---3.40.0850.54x21.7x
spectralnormnumeric131080642.8474.72x0.28x

Geometric mean MIR/Node.js: 0.94x — Lambda faster on 6/10 benchmarks Geometric mean MIR/Python: 0.70x — Lambda faster on 8/10 benchmarks


KOSTYA Benchmarks

Community benchmarks from kostya/benchmarks comparing languages on common tasks.

BenchmarkCategoryMIRC2MIRLambdaJSQuickJSNode.jsPythonMIR/NodeMIR/Py
brainfuckinterpreter1652802.31s906456913.70x0.24x
matmulnumeric8.81282.83s546165350.56x0.02x
primesnumeric7.31025974.5971.62x0.08x
base64string220221900182188512.5x2.59x
levenshteinstring7.71371554.0711.92x0.11x
json_gendata656779216.38.310.3x7.76x
collatznumeric30134018.53s6.22s1.42s8.00s0.21x0.04x

Geometric mean MIR/Node.js: 2.09x — Lambda slower on 2/7 benchmarks Geometric mean MIR/Python: 0.22x — Lambda faster on 5/7 benchmarks


LARCENY Benchmarks

Classic Gabriel/Larceny Scheme benchmark suite testing diverse functional programming patterns.

BenchmarkCategoryMIRC2MIRLambdaJSQuickJSNode.jsPythonMIR/NodeMIR/Py
trianglsearch1791.11s6.82s2.23s682.68s2.62x0.07x
array1array0.555.80.55371.8400.30x0.01x
derivsymbolic2021894693.8265.35x0.76x
diviteriterative27227161.97s26.85s47326.25s0.57x0.01x
divrecrecursive0.847.40.82387.9450.11x0.02x
gcbenchallocation4694392.86s6672525719.0x1.83x
paraffinscombinat0.330.926.12.81.02.90.33x0.11x
pnpolynumeric59533122066.11129.67x0.52x
primesiterative7.29.726974.71211.53x0.06x
puzzlesearch3.81782293.2211.16x0.18x
quicksortsorting3.16.855191.6261.90x0.12x
raynumeric7.16.940143.5122.02x0.61x

Geometric mean MIR/Node.js: 1.47x — Lambda slower on 4/12 benchmarks Geometric mean MIR/Python: 0.12x — Lambda faster on 11/12 benchmarks


JetStream Benchmarks

Benchmarks from Apple's JetStream suite (SunSpider + Octane). Tests numeric computation, 3D rendering, crypto, and data structures.

BenchmarkCategoryMIRC2MIRLambdaJSQuickJSNode.jsPythonMIR/NodeMIR/Py
nbodynumeric47851.86s---5.51468.50x0.32x
cube3d3d24812122818461.31x0.52x
navier_stokesnumeric8238090.2395141.84s56.8x0.45x
richardsmacro259245566---8.322531.3x1.15x
splaydata165---49199203268.07x0.51x
deltabluemacro171848---11181.61x0.96x
hashmapdata106106---323161846.50x0.58x
crypto_sha1crypto17201442229.03211.85x0.05x
raytrace3d3d3484357201701914418.6x2.42x

Geometric mean MIR/Node.js: 7.28x — Lambda slower on 0/9 benchmarks Geometric mean MIR/Python: 0.52x — Lambda faster on 7/9 benchmarks


Overall Summary

MIR Direct vs Node.js V8 (Self-Reported Exec Time)

SuiteGeo. MeanLambda WinsNode WinsTotal
R7RS0.44x7310
AWFY0.62x10414
BENG0.94x6410
KOSTYA2.09x257
LARCENY1.47x4812
JetStream7.28x099
Overall (raw)1.21x293362
Overall (dedup)1.05x282856

Ratio < 1.0 = Lambda MIR is faster. Ratio > 1.0 = Node.js is faster. Dedup note: 56 unique benchmarks out of 62 total entries. Duplicates (same name across suites): deltablue, mandelbrot, nbody, primes, richards — best time per engine is used.

Excluding JetStream (50 unique benchmarks): 0.83x — Lambda wins 28/50

MIR Direct vs Python (Self-Reported Exec Time)

SuiteGeo. MeanLambda WinsPython WinsTotal Compared
R7RS0.07x9110
AWFY0.00x11112
BENG0.70x8210
KOSTYA0.22x527
LARCENY0.12x11112
JetStream0.52x729
Overall (raw)0.09x51960
Overall (dedup)0.08x47855

Lambda MIR is overwhelmingly faster than CPython across all suites.


Performance Tiers (MIR vs Node.js)

TierCountBenchmarks
Lambda >2× faster (< 0.5×)20awfy/list (0.05x), r7rs/sumfp (0.08x), awfy/permute (0.08x), larceny/divrec (0.11x), r7rs/fft (0.11x), awfy/sieve (0.14x), beng/fasta (0.18x), beng/fannkuch (0.18x), r7rs/tak (0.19x), awfy/towers (0.19x), kostya/collatz (0.21x), awfy/queens (0.23x), r7rs/sum (0.23x), beng/pidigits (0.23x), larceny/array1 (0.30x), awfy/storage (0.30x), r7rs/cpstak (0.30x), larceny/paraffins (0.33x), r7rs/mbrot (0.34x), awfy/bounce (0.35x)
Lambda faster (0.5–1.0×)9beng/regexredux (0.50x), beng/revcomp (0.54x), awfy/json (0.54x), kostya/matmul (0.56x), larceny/diviter (0.57x), beng/knucleotide (0.58x), awfy/havlak (0.66x), r7rs/ack (0.72x), awfy/mandelbrot (1.00x)
Comparable (1.0–2.0×)10larceny/puzzle (1.16x), r7rs/fib (1.23x), jetstream/cube3d (1.31x), larceny/primes (1.53x), jetstream/deltablue (1.61x), kostya/primes (1.62x), beng/binarytrees (1.76x), jetstream/crypto_sha1 (1.85x), larceny/quicksort (1.90x), kostya/levenshtein (1.92x)
Node faster (2.0–5.0×)6larceny/ray (2.02x), r7rs/fibfp (2.11x), larceny/triangl (2.62x), kostya/brainfuck (3.70x), r7rs/nqueens (3.72x), beng/spectralnorm (4.72x)
Node >5× faster (> 5.0×)17awfy/deltablue (5.07x), awfy/richards (5.29x), larceny/deriv (5.35x), beng/nbody (5.84x), awfy/cd (5.94x), jetstream/hashmap (6.50x), jetstream/splay (8.07x), awfy/nbody (8.38x), jetstream/nbody (8.50x), beng/mandelbrot (9.13x), larceny/pnpoly (9.67x), kostya/json_gen (10.28x), kostya/base64 (12.51x), jetstream/raytrace3d (18.64x), larceny/gcbench (19.00x), jetstream/richards (31.32x), jetstream/navier_stokes (56.82x)

Improvement over Round 3

MIR Direct Performance Changes (R3 → R4)

BenchmarkSuiteR3 (ms)R4 (ms)Speedup
havlakAWFY183613.00×
cdAWFY5282202.40×
jsonAWFY3.31.52.20×
cube3dJetStream49242.08×
storageAWFY0.330.191.70×
deltablueAWFY99641.54×
listAWFY0.0320.0231.39×

Overall MIR improvement (geo mean, 62 benchmarks): 8.0% faster

Suite-Level Comparison (MIR/Node.js Geometric Mean)

SuiteR3 Geo MeanR4 Geo MeanChange
R7RS0.44x0.44x↓ (1% worse)
AWFY0.83x0.62x↑ improved (1% better)
BENG0.93x0.94x↓ (1% worse)
KOSTYA2.09x2.09x↓ (1% worse)
LARCENY1.48x1.47x↑ improved (1% better)
JetStream7.90x7.28x↑ improved (1% better)

Lambda JS Engine — R4 Status

LambdaJS was not re-run in R4 (only MIR and C2MIR engines were benchmarked). LambdaJS results are carried over from R3. Current R3 coverage:

  • AWFY: All 14 benchmarks passing (bounce, storage, json, deltablue, havlak, cd included)
  • R7RS: All 10 benchmarks (except mbrot)
  • BENG: binarytrees, fannkuch, fasta, knucleotide, mandelbrot, nbody, pidigits, regexredux, revcomp, spectralnorm
  • KOSTYA: brainfuck, matmul, primes, levenshtein, json_gen, collatz
  • LARCENY: All 12 benchmarks

Memory Profiling (Peak RSS)

Peak resident set size measured via /usr/bin/time -l (macOS). Values in MB. Includes runtime, JIT compiler, and all loaded libraries for each engine.

R7RS — Peak RSS (MB)

BenchmarkMIRC2MIRLambdaJSQuickJSNode.jsPython
fib3635321.84011
fibfp4140321.74011
tak3635311.84011
cpstak3635311.74011
sum3535311.74011
sumfp3535361.74211
nqueens3937721.74311
fft3737361.74211
mbrot3736---1.74211
ack363531---4011

AWFY — Peak RSS (MB)

BenchmarkMIRC2MIRLambdaJSQuickJSNode.jsPython
sieve3635321.941---
permute3635321.841---
queens3635321.742---
towers3636321.642---
bounce3836---1.741---
list3635321.740---
storage3736---2.442---
mandelbrot36352251.743---
nbody4241331.936---
richards7774371.844---
json4745---3.043---
deltablue5753---1.937---
havlak115111---3094---
cd6968---4.357---

BENG — Peak RSS (MB)

BenchmarkMIRC2MIRLambdaJSQuickJSNode.jsPython
binarytrees4746722.94311
fannkuch3836321.94111
fasta4138331.94411
knucleotide414232---4312
mandelbrot7169481.74211
nbody4242371.74311
pidigits3736321.73711
regexredux393933---3611
revcomp383833---3811
spectralnorm5652661.94311

KOSTYA — Peak RSS (MB)

BenchmarkMIRC2MIRLambdaJSQuickJSNode.jsPython
brainfuck382003232.310411
matmul412866492.74412
primes4343322.74221
base6414141902356.44912
levenshtein3837361.94111
json_gen700699492.94611
collatz36355031.84111

LARCENY — Peak RSS (MB)

BenchmarkMIRC2MIRLambdaJSQuickJSNode.jsPython
triangl3936331.84111
array13635311.84011
deriv53531061.94411
diviter3635311.64111
divrec3635312.24011
gcbench261259667206015
paraffins4037321.84211
pnpoly10096491.74311
primes3736321.84111
puzzle3736---1.84111
quicksort3736321.94211
ray4948421.74311

JetStream — Peak RSS (MB)

BenchmarkMIRC2MIRLambdaJSQuickJSNode.jsPython
nbody122190------44---
cube3d9279------55---
navier_stokes13101307------49---
richards312310------44---
splay240---------147---
deltablue5754------51---
hashmap4948------52---
crypto_sha15347------44---
raytrace3d148145------53---

Memory Summary — Average Peak RSS per Suite (MB)

SuiteMIRC2MIRLambdaJSQuickJSNode.jsPythonMIR/NodeMIR/QJS
R7RS3736371.741110.90x21.5x
AWFY5048574.146---1.09x12.2x
BENG4544422.041111.10x23.1x
KOSTYA3304582323.052136.29x111.5x
LARCENY6362993.443111.46x18.8x
JetStream265272------60---4.44x---

Lambda MIR uses 2.79× the memory of Node.js (132 MB vs 47 MB average). QuickJS is the most memory-efficient at 3 MB average — 47× less than Lambda MIR.

Memory footprint is dominated by engine/runtime overhead; actual benchmark data is small. QuickJS's tiny interpreter has minimal memory overhead. Node.js includes the full V8 engine.


Key Findings

1. Overall: Lambda MIR competitive with Node.js V8

Across 56 unique benchmarks with both MIR and Node.js results, the geometric mean ratio is 1.05x. Excluding the new JetStream suite (which ports are not yet optimized), Lambda achieves 0.83x on 50 unique benchmarks, winning 28 of 50.

2. Lambda MIR dominates CPython

Across 55 unique benchmarks with Python comparisons, Lambda MIR is 13× faster (geo mean 0.08x). CPython's interpreted execution cannot match JIT-compiled code on compute-intensive tasks. Lambda wins on all suites, with particular dominance on tight loops and numeric code (AWFY micro-benchmarks: 1000–30000× faster).

3. Strengths: Micro-benchmarks and numeric code

Lambda MIR excels on small, tight computational benchmarks:

  • R7RS suite (0.43x): 2.3× faster on average — strong tail-call optimization, native integer/float arithmetic
  • AWFY micro-benchmarks: sieve (0.14x), list (0.04x), permute (0.08x) — highly efficient JIT for simple loops
  • FFT (0.11x): 9× speedup from typed array inline fast paths
  • Collatz (0.21x): 5× faster than Node.js on integer-heavy iteration

4. Weaknesses: OOP-heavy and allocation-intensive code

Node.js V8's optimizing JIT (TurboFan) significantly outperforms Lambda on:

  • Class-heavy benchmarks: richards (5.29x AWFY), cd (5.94x) — V8's hidden classes and inline caches
  • Heavy allocation/GC: gcbench (19x), base64 (12.5x) — V8's generational GC advantage
  • JetStream suite (7.28x): Complex OOP-style benchmarks where V8's mature optimizations dominate

5. JetStream: New frontier for optimization

The JetStream benchmarks (ported from Apple's JS benchmark suite) show Lambda MIR running slower than Node.js on all 9 benchmarks (geo mean ~7×). Workloads are now synchronized to the original heavy JetStream workloads. Key remaining bottlenecks:

  • navier_stokes (57×): Heavy array-based PDE solver — needs typed array optimization for this pattern
  • richards (31×): OOP task scheduler — 50 iterations × 1000 COUNT exposes class/method dispatch overhead
  • raytrace3d (18×): Object-heavy 3D computation — property access patterns
  • splay (8×): Red-black tree operations — property access patterns
  • nbody (8.5×): Numeric simulation — 36000 advance steps per run
  • deltablue (1.6×): Constraint solver — close to competitive at 20 iterations
  • cube3d (1.3×): 3D rendering — much improved from R3 (49ms → 24ms) These represent clear optimization targets for future MIR engine improvements.

6. MIR JIT improvements from Round 3 (LMD_TYPE_LIST removal)

Removing LMD_TYPE_LIST and unifying list/array handling delivered significant improvements:

  • havlak: 183 → 61ms (3.0× faster) — graph traversal, list-heavy data structure
  • cd: 528 → 220ms (2.4× faster) — collision detection with many list operations
  • json: 3.3 → 1.5ms (2.2× faster) — JSON macro benchmark
  • cube3d: 49 → 24ms (2.0× faster) — 3D rendering with array operations
  • storage: 0.33 → 0.19ms (1.7× faster) — storage micro-benchmark
  • deltablue: 99 → 64ms (1.5× faster) — constraint solver macro benchmark
  • list: 0.032 → 0.023ms (1.4× faster) — list micro-benchmark
  • Overall: ~8% faster across 62 comparable benchmarks

7. Lambda JS engine

LambdaJS results are unchanged from R3 (not re-run in R4). R3 coverage:

  • All AWFY benchmarks pass including bounce, storage, json, deltablue, havlak, and cd
  • BENG/fannkuch, BENG/mandelbrot, KOSTYA/collatz passing

8. QuickJS comparison

QuickJS (pure interpreter) is generally 2–10× slower than Node.js V8, as expected. Lambda MIR is faster than QuickJS on most benchmarks, confirming Lambda's JIT advantage.

9. C2MIR vs MIR Direct

The two Lambda JIT paths produce similar results. Notable differences:

  • C2MIR slightly faster on: r7rs/sum (0.27 vs 1.8ms), nqueens (6.7 vs 6.6ms)
  • MIR Direct faster on: matmul (8.8 vs 128ms), cube3d (24 vs 81ms), list (0.023 vs 0.62ms)
  • MIR Direct has lower compilation overhead and is the default path

10. Memory footprint

Lambda MIR's peak RSS averages ~2.8× Node.js memory, dominated by the MIR JIT compiler and runtime overhead. Key observations:

  • R7RS/micro-benchmarks: MIR ~37 MB vs Node ~41 MB — Lambda is lighter for small programs
  • KOSTYA/LARCENY/JetStream: MIR 63–330 MB vs Node 43–60 MB — Lambda's GC and data model use more RAM on heavy workloads
  • QuickJS is the most memory-efficient at ~3 MB average (pure interpreter, minimal overhead)
  • Outliers: base64 (1,414 MB MIR), navier_stokes (1,310 MB MIR) — indicate optimization opportunities for array-heavy benchmarks

Notes

  • Self-reported exec time measures only the computation, excluding process startup, JIT compilation warmup, and file I/O.
  • AWFY JS benchmarks use the official source from ref/are-we-fast-yet/benchmarks/JavaScript/. AWFY Python benchmarks use the official Python port with harness.
  • AWFY Python micro-benchmarks (sieve, permute, queens, etc.) show extreme Lambda advantage because CPython interprets tight loops ~10,000× slower than JIT-compiled code.
  • AWFY Python benchmarks use the official Python port with harness. Class names: NBody, DeltaBlue, CD (not capitalize()).
  • LambdaJS now passes all AWFY benchmarks including bounce, storage, json, deltablue, havlak, and cd (results from R3, not re-run in R4).
  • QuickJS fails on ack (R7RS) due to stack overflow on deep recursion.
  • JetStream benchmarks run on MIR, C2MIR, Node.js, and Python (for deltablue, richards, nbody). No LambdaJS/QuickJS ports.
  • Python benchmarks not available for: AWFY/cd, JetStream/cube3d, JetStream/navier_stokes, JetStream/splay, JetStream/hashmap, JetStream/crypto_sha1, JetStream/raytrace3d.
  • All times in milliseconds unless noted with 's' suffix (seconds).
  • KOSTYA/json_gen benchmark was broken in an earlier commit (commit f2f0c3fd9, incorrect string syntax); fixed in this round. Results are now correct (~65ms).
  • LMD_TYPE_LIST removal (R4): LMD_TYPE_LIST was replaced by LMD_TYPE_ARRAY throughout the runtime. All list/array operations now use a unified type, improving performance on OOP-heavy and collection-intensive benchmarks.
  • Workload synchronization: Duplicate benchmark names across suites use identical heavy workloads synchronized to original JetStream — AWFY/BENG/JetStream mandelbrot N=500, nbody 36000 steps, richards 50×COUNT=1000, deltablue 20×chain(100), Larceny/Kostya primes sieve(1M).