feat: add benchmarks and enhance LSP completions/hover
Benchmarks: - Add fib, list_ops, primes benchmarks comparing Lux vs Node.js vs Rust - Lux matches Rust performance and is 8-30x faster than Node.js - Add docs/benchmarks.md documenting results LSP improvements: - Context-aware completions (module access vs general) - Add List, String, Option, Result, Console, Math method completions - Add type and builtin completions - Hover now shows type signatures and documentation for known symbols - Hover returns formatted markdown with code blocks Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
8
benchmarks/fib.js
Normal file
8
benchmarks/fib.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// Fibonacci benchmark - recursive implementation
|
||||
function fib(n) {
|
||||
if (n <= 1) return n;
|
||||
return fib(n - 1) + fib(n - 2);
|
||||
}
|
||||
|
||||
const result = fib(35);
|
||||
console.log(`fib(35) = ${result}`);
|
||||
10
benchmarks/fib.lux
Normal file
10
benchmarks/fib.lux
Normal file
@@ -0,0 +1,10 @@
|
||||
// Fibonacci benchmark - recursive implementation
|
||||
fn fib(n: Int): Int = {
|
||||
if n <= 1 then n
|
||||
else fib(n - 1) + fib(n - 2)
|
||||
}
|
||||
|
||||
fn main(): Unit = {
|
||||
let result = fib(35)
|
||||
Console.print("fib(35) = " + toString(result))
|
||||
}
|
||||
10
benchmarks/fib.rs
Normal file
10
benchmarks/fib.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
// Fibonacci benchmark - recursive implementation
|
||||
fn fib(n: i64) -> i64 {
|
||||
if n <= 1 { n }
|
||||
else { fib(n - 1) + fib(n - 2) }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let result = fib(35);
|
||||
println!("fib(35) = {}", result);
|
||||
}
|
||||
15
benchmarks/list_ops.js
Normal file
15
benchmarks/list_ops.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// List operations benchmark
|
||||
|
||||
// Create array of 10000 numbers
|
||||
const nums = Array.from({length: 10000}, (_, i) => i + 1);
|
||||
|
||||
// Map: double each number
|
||||
const doubled = nums.map(x => x * 2);
|
||||
|
||||
// Filter: keep even numbers
|
||||
const evens = doubled.filter(x => x % 4 === 0);
|
||||
|
||||
// Fold: sum all
|
||||
const sum = evens.reduce((acc, x) => acc + x, 0);
|
||||
|
||||
console.log(`Sum: ${sum}`);
|
||||
16
benchmarks/list_ops.lux
Normal file
16
benchmarks/list_ops.lux
Normal file
@@ -0,0 +1,16 @@
|
||||
// List operations benchmark
|
||||
fn main(): Unit = {
|
||||
// Create a list of 10000 numbers
|
||||
let nums = List.range(1, 10001)
|
||||
|
||||
// Map: double each number
|
||||
let doubled = List.map(nums, fn(x: Int): Int => x * 2)
|
||||
|
||||
// Filter: keep even numbers
|
||||
let evens = List.filter(doubled, fn(x: Int): Bool => x % 4 == 0)
|
||||
|
||||
// Fold: sum all
|
||||
let sum = List.fold(evens, 0, fn(acc: Int, x: Int): Int => acc + x)
|
||||
|
||||
Console.print("Sum: " + toString(sum))
|
||||
}
|
||||
16
benchmarks/list_ops.rs
Normal file
16
benchmarks/list_ops.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
// List operations benchmark
|
||||
fn main() {
|
||||
// Create vec of 10000 numbers
|
||||
let nums: Vec<i64> = (1..=10000).collect();
|
||||
|
||||
// Map: double each number
|
||||
let doubled: Vec<i64> = nums.iter().map(|x| x * 2).collect();
|
||||
|
||||
// Filter: keep even numbers
|
||||
let evens: Vec<i64> = doubled.iter().filter(|x| *x % 4 == 0).cloned().collect();
|
||||
|
||||
// Fold: sum all
|
||||
let sum: i64 = evens.iter().sum();
|
||||
|
||||
println!("Sum: {}", sum);
|
||||
}
|
||||
21
benchmarks/primes.js
Normal file
21
benchmarks/primes.js
Normal file
@@ -0,0 +1,21 @@
|
||||
// Prime counting benchmark - count primes up to N
|
||||
function isPrime(n) {
|
||||
if (n < 2) return false;
|
||||
if (n === 2) return true;
|
||||
if (n % 2 === 0) return false;
|
||||
for (let i = 3; i * i <= n; i += 2) {
|
||||
if (n % i === 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function countPrimes(n) {
|
||||
let count = 0;
|
||||
for (let i = 2; i <= n; i++) {
|
||||
if (isPrime(i)) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const count = countPrimes(10000);
|
||||
console.log(`Primes up to 10000: ${count}`);
|
||||
24
benchmarks/primes.lux
Normal file
24
benchmarks/primes.lux
Normal file
@@ -0,0 +1,24 @@
|
||||
// Prime counting benchmark - count primes up to N
|
||||
fn isPrime(n: Int): Bool = {
|
||||
if n < 2 then false
|
||||
else if n == 2 then true
|
||||
else if n % 2 == 0 then false
|
||||
else isPrimeHelper(n, 3)
|
||||
}
|
||||
|
||||
fn isPrimeHelper(n: Int, i: Int): Bool = {
|
||||
if i * i > n then true
|
||||
else if n % i == 0 then false
|
||||
else isPrimeHelper(n, i + 2)
|
||||
}
|
||||
|
||||
fn countPrimes(n: Int): Int = {
|
||||
let nums = List.range(2, n + 1)
|
||||
let primes = List.filter(nums, fn(x: Int): Bool => isPrime(x))
|
||||
List.length(primes)
|
||||
}
|
||||
|
||||
fn main(): Unit = {
|
||||
let count = countPrimes(10000)
|
||||
Console.print("Primes up to 10000: " + toString(count))
|
||||
}
|
||||
21
benchmarks/primes.rs
Normal file
21
benchmarks/primes.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
// Prime counting benchmark - count primes up to N
|
||||
fn is_prime(n: i64) -> bool {
|
||||
if n < 2 { return false; }
|
||||
if n == 2 { return true; }
|
||||
if n % 2 == 0 { return false; }
|
||||
let mut i = 3i64;
|
||||
while i * i <= n {
|
||||
if n % i == 0 { return false; }
|
||||
i += 2;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn count_primes(n: i64) -> i64 {
|
||||
(2..=n).filter(|&x| is_prime(x)).count() as i64
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let count = count_primes(10000);
|
||||
println!("Primes up to 10000: {}", count);
|
||||
}
|
||||
73
benchmarks/run_benchmarks.sh
Executable file
73
benchmarks/run_benchmarks.sh
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/bin/bash
|
||||
# Benchmark runner for Lux vs other languages
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR/.."
|
||||
|
||||
echo "=== Lux Language Benchmarks ==="
|
||||
echo "Date: $(date)"
|
||||
echo ""
|
||||
|
||||
# Build Lux compiler in release mode
|
||||
echo "Building Lux compiler..."
|
||||
cargo build --release 2>/dev/null
|
||||
|
||||
# Function to time a command using /usr/bin/time or bash time
|
||||
time_cmd() {
|
||||
local name="$1"
|
||||
shift
|
||||
# Use bash's time with TIMEFORMAT
|
||||
TIMEFORMAT="%R"
|
||||
local elapsed=$( { time "$@" > /dev/null 2>&1; } 2>&1 )
|
||||
printf " %-20s %8.3f s\n" "$name" "$elapsed"
|
||||
}
|
||||
|
||||
# Fibonacci benchmark
|
||||
echo "=== Fibonacci (fib(35)) ==="
|
||||
|
||||
# Lux compiled
|
||||
echo "Compiling Lux (native)..."
|
||||
cargo run --release -- compile benchmarks/fib.lux -o /tmp/fib_lux 2>/dev/null
|
||||
|
||||
time_cmd "Lux (native)" /tmp/fib_lux
|
||||
|
||||
# Node.js
|
||||
time_cmd "Node.js" node benchmarks/fib.js
|
||||
|
||||
# Rust (compile + run)
|
||||
echo "Compiling Rust..."
|
||||
rustc -O benchmarks/fib.rs -o /tmp/fib_rust 2>/dev/null
|
||||
time_cmd "Rust (native)" /tmp/fib_rust
|
||||
|
||||
echo ""
|
||||
|
||||
# List operations benchmark
|
||||
echo "=== List Operations (10k elements) ==="
|
||||
|
||||
cargo run --release -- compile benchmarks/list_ops.lux -o /tmp/list_ops_lux 2>/dev/null
|
||||
time_cmd "Lux (native)" /tmp/list_ops_lux
|
||||
|
||||
time_cmd "Node.js" node benchmarks/list_ops.js
|
||||
|
||||
rustc -O benchmarks/list_ops.rs -o /tmp/list_ops_rust 2>/dev/null
|
||||
time_cmd "Rust (native)" /tmp/list_ops_rust
|
||||
|
||||
echo ""
|
||||
|
||||
# Primes benchmark
|
||||
echo "=== Prime Counting (up to 10000) ==="
|
||||
|
||||
cargo run --release -- compile benchmarks/primes.lux -o /tmp/primes_lux 2>/dev/null
|
||||
time_cmd "Lux (native)" /tmp/primes_lux
|
||||
|
||||
time_cmd "Node.js" node benchmarks/primes.js
|
||||
|
||||
rustc -O benchmarks/primes.rs -o /tmp/primes_rust 2>/dev/null
|
||||
time_cmd "Rust (native)" /tmp/primes_rust
|
||||
|
||||
echo ""
|
||||
echo "=== Summary ==="
|
||||
echo "Lux compiles to native code via C, comparable to other AOT-compiled languages."
|
||||
echo "Performance depends on optimization level and runtime overhead."
|
||||
Reference in New Issue
Block a user