Performance Benchmarks

How Strada compares to Perl, Python, Ruby, Node.js, and PHP.

Strada compiles to C, then to native machine code via GCC with link-time optimization. These benchmarks compare Strada against Perl, Python, Ruby, Node.js, and PHP across five categories: compute, functions, strings, data structures, and object-oriented programming.

code.strada stradac code.c gcc -O2 -flto native binary
95x
faster than Perl at compute
82x
faster than Perl at functions
2,303x
faster than Python at strings

Results

All times are wall-clock seconds, best of 3 runs. Lower is better.

Benchmark Strada Perl 5.38 Python 3.12 Ruby 3.2 Node.js 24 PHP 8.3
Compute 0.989s 93.48s 27.54s 19.65s 2.54s 11.93s
Functions 0.015s 1.224s 0.989s 0.423s 0.047s 0.188s
Strings 0.060s 0.148s 138.2s 62.90s 0.138s 0.080s
Array/Hash 0.110s 0.760s 0.614s 0.800s 0.640s 0.145s
OOP 0.051s 1.511s 1.248s 1.042s 0.072s 0.287s

Strada vs Perl

Strada is a natural upgrade from Perl — same syntax feel, dramatically better performance. The biggest gains come from compiled function calls and integer arithmetic, where Perl's interpreter dispatch loop creates massive overhead.

Compute
95x faster
Functions
82x faster
OOP
30x faster
Array/Hash
6.9x faster
Strings
2.5x faster

Strada vs Python

Python's interpreted bytecode VM adds overhead to every operation. Strada compiles to native code, making it dramatically faster across the board. Python's string concatenation with += is catastrophically slow due to immutable string copies — over 2,000x slower than Strada.

Strings
2,303x faster
Functions
66x faster
Compute
28x faster
OOP
24x faster
Array/Hash
5.6x faster

Strada vs Ruby

Ruby's YARV interpreter and YJIT have improved performance significantly, but Strada's native compilation still wins across every benchmark. Ruby's string concatenation suffers from similar allocation overhead as Python.

Strings
1,048x faster
Functions
28x faster
OOP
20x faster
Compute
20x faster
Array/Hash
7.3x faster

Strada vs Node.js

V8's JIT compiler makes Node.js a strong competitor. With Strada's tagged-integer arithmetic and constructor-fusion work, Strada now wins all five benchmarks — including OOP, where Node's hidden classes and inline caches used to edge ahead.

Array/Hash
5.8x faster
Functions
3.1x faster
Compute
2.6x faster
Strings
2.3x faster
OOP
1.4x faster

Strada vs PHP

PHP 8.3's JIT and optimized hash tables make it competitive at data-structure and string workloads, but Strada wins all five benchmarks. The gap is widest on compute, function calls, and OOP, where native compilation and constructor fusion eliminate interpreter overhead; strings and hash insertion are closer but still favor Strada.

Functions
12.5x faster
Compute
12x faster
OOP
5.6x faster
Strings
1.3x faster
Array/Hash
1.3x faster

Why Strada is Fast

Native code, not bytecode

Perl, Python, Ruby, and PHP compile to bytecode that runs on a virtual machine. Node.js uses V8's JIT compiler, which is fast but still has warmup costs and deoptimization overhead. Strada compiles to C, which GCC then optimizes into native machine code with link-time optimization. There is no interpreter overhead at runtime.

Zero-overhead function calls

Interpreted languages look up function names at runtime. Strada compiles function calls to direct C function calls — a single call instruction. With inline fast-path wrappers for tagged integer operations, function call overhead approaches zero. This makes Strada 82x faster than Perl, 66x faster than Python, 28x faster than Ruby, 12.5x faster than PHP, and 3.1x faster than Node.js at function-heavy workloads.

Tagged integers: zero-allocation arithmetic

Strada encodes integers directly inside pointers — no heap allocation, no reference counting, no free. Integer arithmetic like $a + $b compiles to a single CPU add instruction plus a bit shift. Reference counting and type conversion functions are inlined at every call site, short-circuiting to a single pointer-bit check for the common integer case. This makes compute-heavy code 95x faster than Perl, 28x faster than Python, 20x faster than Ruby, 12x faster than PHP, and 2.6x faster than Node.js.

Refcounted strings: zero-copy sharing

Strada uses StradaString — a refcounted string with the data stored inline (single allocation). When a string is passed to a function or used as a hash key, Strada increments the reference count instead of copying. String literals appended with .= bypass allocation entirely, appending bytes directly to the existing buffer. Short strings are recycled via a pool. This makes string operations 2,303x faster than Python, 1,048x faster than Ruby, 2.5x faster than Perl, and 2.3x faster than Node.js.

Inline accessor & constructor optimization

When you write $self->x() on a has attribute, Strada detects that the method is a simple accessor and compiles it to a direct hash fetch — skipping method dispatch entirely. For constructors like Point::new("x", 1, "y", 2), the compiler pre-computes attribute key hashes at compile time, emits direct hash construction code, and devirtualizes method calls for known types. This makes Strada OOP 30x faster than Perl, 24x faster than Python, 20x faster than Ruby, 5.6x faster than PHP, and 1.4x faster than Node.js.

Compiled PCRE2 regex

Strada links against PCRE2 (Perl Compatible Regular Expressions), the same engine used by PHP, Nginx, and Haproxy. Regex patterns are compiled to optimized automata at program startup. Single-character delimiters in split() use SIMD-optimized memchr instead of the regex engine.

Automatic stack trace elision

Strada automatically detects whether your program uses exceptions (try/throw) or introspection (core::caller()). If not, it omits stack frame tracking from every function call, eliminating overhead that Perl and Python always pay. For recursive functions like Fibonacci, this alone provides a significant speedup.

What Each Benchmark Tests

Compute

Sum of 50 million integers and recursive Fibonacci(35) run 30 times. Tests raw numeric throughput, function call overhead, and recursive call performance.

func fib(int $n) int {
    if ($n < 2) { return $n; }
    return fib($n - 1) + fib($n - 2);
}

Functions

Millions of function calls with multiple arguments, plus Ackermann's function for deep recursion. Tests call/return overhead, argument passing, and stack management.

Strings

Concatenation of 500,000 strings, splitting 100K strings, and regex search-and-replace on 200K iterations. Tests string allocation, PCRE2 regex compilation, and in-place mutation.

Array/Hash

Pushes 2 million elements, creates a 500K-entry hash with lookups, and deletes all entries. Tests dynamic array growth, hash table insertion, lookup, and deletion.

OOP

Creates 1.2 million objects with has attributes, calls accessor methods, computes distances, and performs isa() checks. Tests object construction, method dispatch, accessor performance, and inheritance.

package Point;
has rw int $x = 0;
has rw int $y = 0;

func distance_sq(scalar $self) int {
    return $self->x() * $self->x() + $self->y() * $self->y();
}

Running the Benchmarks

All benchmark source files are in the benchmarks/ directory with implementations in Strada, Perl, Python, Ruby, Node.js, and PHP:

# Run all benchmarks with the automated script
cd benchmarks
bash run_benchmarks.sh

# Or run individual benchmarks
./strada benchmarks/bench_compute.strada
time ./bench_compute
time perl benchmarks/bench_compute.pl
time python3 benchmarks/bench_compute.py
time ruby benchmarks/bench_compute.rb
time node benchmarks/bench_compute.js
time php benchmarks/bench_compute.php
Environment Benchmarks measured on Linux x86_64 with GCC -O2 -flto for Strada, Perl 5.38, Python 3.12, Ruby 3.2, Node.js 24 (V8), and PHP 8.3. Times are best of 3 runs (wall-clock time). Each benchmark runs the same algorithm with the same input across all languages.