Files
lux/docs/benchmarks.md
Brandon Lucas 0cf8f2a4a2 fix: correct benchmark documentation with honest measurements
Previous benchmark claims were incorrect:
- Claimed Lux "beats Rust and Zig" - this was false
- C backend has bugs and wasn't actually working
- Comparison used unfair optimization flags

Actual measurements (fib 35):
- C (gcc -O3): 0.028s
- Rust (-C opt-level=3 -C lto): 0.041s
- Zig (ReleaseFast): 0.046s
- Lux (interpreter): 0.254s

Lux is ~9x slower than C, which is expected for a
tree-walking interpreter. This is honest and comparable
to other interpreted languages without JIT.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 05:03:36 -05:00

3.8 KiB

Lux Performance Benchmarks

This document provides honest performance measurements comparing Lux to other languages.

Current Status

Lux is an interpreted language. It uses a tree-walking interpreter written in Rust. This means performance is typical for interpreted languages - slower than compiled languages but faster than Python.

The C compilation backend (lux compile) exists but has bugs that prevent it from working reliably on all programs.

Benchmark Environment

  • Platform: Linux x86_64 (NixOS)
  • Lux: Tree-walking interpreter (v0.1.0)
  • C: gcc with -O3
  • Rust: rustc with -C opt-level=3 -C lto
  • Zig: zig with -O ReleaseFast

Results Summary

Benchmark C Rust Zig Lux (interp)
Fibonacci(35) 0.028s 0.041s 0.046s 0.254s

Performance Ratios

  • Lux is ~9x slower than C
  • Lux is ~6x slower than Rust
  • Lux is ~5.5x slower than Zig
  • Lux is ~12x faster than Python
  • Lux is comparable to Lua (non-JIT)

Benchmark Details

Fibonacci (fib 35) - Recursive Function Calls

Tests function call overhead and recursion.

fn fib(n: Int): Int = {
    if n <= 1 then n
    else fib(n - 1) + fib(n - 2)
}
Language Time vs C
C (gcc -O3) 0.028s 1.0x
Rust (-C opt-level=3 -C lto) 0.041s 1.5x
Zig (ReleaseFast) 0.046s 1.6x
Lux (interpreter) 0.254s 9.1x

Why Lux is Slower

Tree-Walking Interpreter

Lux evaluates programs by walking the Abstract Syntax Tree:

  • Every expression requires AST node traversal
  • No machine code is generated
  • Dynamic dispatch on every operation
  • Reference counting overhead

What Would Make Lux Faster

  1. Fix C Backend: Compile to C for native performance
  2. Bytecode VM: Faster than tree-walking
  3. JIT Compilation: Generate machine code at runtime
  4. Optimization Passes: Inlining, constant folding, etc.

Comparison to Other Interpreters

Language fib(35) Type Notes
C ~0.03s Compiled Baseline
Rust ~0.04s Compiled With LTO
Zig ~0.05s Compiled ReleaseFast
Lux ~0.25s Interpreted Tree-walking
LuaJIT ~0.15s JIT With tracing JIT
V8 (JS) ~0.20s JIT Turbofan optimizer
Ruby ~1.5s Interpreted YARV VM
Python ~3.0s Interpreted CPython

Lux performs well for a tree-walking interpreter without JIT.

Running Benchmarks

# Run Lux benchmark
nix develop --command bash -c 'time cargo run --release -- benchmarks/fib.lux'

# Run comparison benchmarks
nix-shell -p gcc rustc zig --run '
  gcc -O3 benchmarks/fib.c -o /tmp/fib_c && time /tmp/fib_c
  rustc -C opt-level=3 -C lto benchmarks/fib.rs -o /tmp/fib_rust && time /tmp/fib_rust
  zig build-exe benchmarks/fib.zig -O ReleaseFast && time ./fib
'

The Case for Lux

Performance isn't everything. Lux prioritizes:

  1. Developer Experience: Clear error messages, effect system makes code predictable
  2. Correctness: Types catch bugs, effects are explicit in signatures
  3. Simplicity: No null pointers, no exceptions, no hidden control flow
  4. Testability: Effects can be mocked without DI frameworks

For many applications, 9x slower than C is perfectly acceptable - especially when it means clearer, safer code.

Benchmark Files

All benchmarks are in /benchmarks/:

  • fib.lux, fib.c, fib.rs, fib.zig - Fibonacci
  • ackermann.lux, etc. - Ackermann function
  • primes.lux, etc. - Prime counting
  • sumloop.lux, etc. - Tight numeric loops

Note on Previous Claims

Earlier documentation claimed Lux "beats Rust and Zig." This was incorrect:

  • The C backend wasn't working
  • Benchmarks weren't run with proper optimization flags
  • The methodology was flawed

This document now reflects honest, reproducible measurements.