Performance Benchmarks

How Strada compares to Perl and Python across real workloads.

Strada compiles to C, then to native machine code via GCC. This gives it a fundamental advantage over interpreted languages for CPU-bound work. These benchmarks compare Strada against Perl 5 and CPython 3 across five categories covering arithmetic, function calls, object-oriented programming, string processing, and data structures.

code.strada stradac code.c gcc -O2 native binary
5.7x
faster than Perl at compute
3.1x
faster than Python at function calls
814x
faster than Python at strings

Results

All times are CPU time (user) in seconds, measured on the same machine. Lower is better.

Benchmark Strada Python 3 Perl 5
Compute 51.94s 155.85s 294.87s
Functions 1.80s 5.57s 5.40s
OOP 3.94s 3.17s 6.90s
Strings 0.79s 644.15s 0.90s
Array/Hash 0.76s 3.22s 2.46s

Strada vs Perl

Compute
5.7x faster
Functions
3.0x faster
OOP
1.8x faster
Strings
1.1x faster
Array/Hash
3.2x faster

Strada wins convincingly across the board. The Array/Hash benchmark saw a dramatic improvement thanks to tagged integers — small integers are now encoded directly in pointers with zero heap allocation, eliminating millions of malloc/free calls in tight loops.

Strada vs Python

Strings
814x faster
Array/Hash
4.2x faster
Functions
3.1x faster
Compute
3.0x faster
OOP
Python 1.2x

The string benchmark is the standout: Strada's compiled PCRE2 regex and in-place string operations are over 800x faster than Python's interpreted approach. Tagged integers give Strada a 4.2x advantage on the Array/Hash benchmark, where integer-heavy loops benefit from zero-allocation arithmetic. Python edges ahead on OOP thanks to CPython's heavily optimized __getattr__ fast paths and dict internals that have been tuned for decades.

Why Strada is Fast

Native code, not bytecode

Perl and Python compile to bytecode that runs on a virtual machine. Every operation — every addition, every function call, every attribute access — goes through an interpreter dispatch loop. Strada compiles to C, which GCC then optimizes into native machine code. There is no interpreter overhead at runtime.

Zero-overhead function calls

In Perl, calling a function means looking up the symbol table at runtime. In Python, function objects are fetched from dictionaries. In Strada, function calls compile to direct C function calls — a single call instruction. This makes Strada 3.0x faster than Perl and 3.1x faster than Python at function-heavy workloads.

Inline accessor 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 the entire method dispatch machinery. Combined with arithmetic expression inlining (sub-expressions like x*x + y*y compile to raw C arithmetic without intermediate allocations), OOP-heavy code runs 1.8x faster than Perl.

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, not interpreted at match time. Combined with in-place string mutation (strada_concat_inplace avoids copies), string operations are 814x faster than Python and competitive with Perl.

Tagged integers: zero-allocation arithmetic

Strada encodes small integers directly inside pointers using tagged pointer representation. When the low bit of a pointer is set, the remaining 63 bits hold the integer value — no heap allocation, no reference counting, no free. This makes integer-heavy operations like loop counters, array indexing, and hash lookups dramatically faster. The Array/Hash benchmark runs in just 0.76s, making Strada 3.2x faster than Perl and 4.2x faster than Python on data-structure workloads. Functions like strada_to_int() handle both tagged and heap-allocated integers transparently.

Where Perl and Python win

Python edges ahead on OOP thanks to CPython's heavily optimized __getattr__ fast paths and decades of dict tuning. For pure object creation and method dispatch, CPython's specializing bytecode compiler gives it an advantage. Strada is closing this gap with inline accessor optimization and arithmetic expression inlining.

What Each Benchmark Tests

Compute

Tight arithmetic loops and recursive Fibonacci. Tests raw numeric throughput and function call overhead in recursive contexts. Strada's compiled arithmetic maps directly to CPU instructions, giving it a large advantage.

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.

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();
}

Strings

Concatenation of 2.5 million characters, splitting 100K strings, and regex search-and-replace. 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.

Running the Benchmarks

All benchmark source files are in the benchmarks/ directory with implementations in Strada, Python, and Perl:

# Build and run all Strada benchmarks
for b in benchmarks/bench_*.strada; do
    ./strada "$b"
    time ./$(basename "$b" .strada)
done

# Compare with Python and Perl
time python3 benchmarks/bench_compute.py
time perl benchmarks/bench_compute.pl
Environment Benchmarks measured on Linux x86_64, GCC with -O2, Perl 5, CPython 3. Times are CPU user time to exclude I/O variance. Each benchmark runs the same algorithm with the same input across all three languages.