QUARK

Roughly five times CPython 3.14, with calls that allocate nothing at all, and not one structural decision in it taken on faith.


5.1×faster than CPython 3.14
2.37nsto evaluate one expression
0allocations per call

Measured against your own Python.

The benchmark runs against whichever Python sits on your own machine, calibrates both sides to the same target duration and keeps the fastest run. A figure from somebody else's hardware tells you nothing about yours.

Run atom benchmark --compare and argue with your own numbers.

One run against CPython 3.14.6
BenchmarkAtomPythonRatio
loop100.2M/s19.6M/s5.10×
arith50.1M/s9.1M/s5.48×
branch100.2M/s14.7M/s6.81×
Your numbers will differ.

Nothing here is assumed.

Every structural decision in Quark was measured against the alternatives, and the alternatives are still in the test suite. Expressions compile down to closures rather than running through an interface. Names resolve to indices while they compile, globals into numbered slots and function locals onto a reusable stack, so a call allocates nothing at all.

Calls used to build a map on every invocation, which turned out to be the overwhelming majority of everything the interpreter allocated. Removing it was worth more than any of the micro-optimisation that came before.

One expression, by dispatch strategy
StrategyPer op
Compiled closures2.37ns
Bytecode machine12.01ns
Interfaces13.14ns
Measured on a Ryzen 7 5700X. Recheck it on yours with go test -bench Dispatch ./src/expr/.

Tried, measured, rejected

A fifth machine word

Reverted

The value type has to stay at four machine words. At five, Go stops returning it in registers and roughly two thirds of the interpreter's speed goes with it. A test fails the build if the struct ever grows, because the cost is invisible in the diff and obvious only in the benchmark.

Closures for statements

Reverted

Closures win decisively for expressions, so the same treatment looked obvious for statements. It came out about 25% slower and was backed out. The expression win came mostly from choosing the operator while compiling, not from closures in themselves.

A bytecode machine

Slower

The usual next step after a tree walker, and it lost by a factor of five. Go has no computed goto, so every opcode leaves through the same switch and the processor sees one unpredictable branch instead of many predictable ones.

NaN-boxing

Unsafe

Not a matter of taste. Go's collector finds pointers through each type's pointer map, so a pointer hidden in the unused bits of a float64 is invisible to it. The object gets freed while it is still being used.


It ships inside one binary.

Quark is not distributed separately and there is nothing to configure. It is what runs when you type atom, and it carries the web server, the reverse proxy, the repl and the formatter with it.

Get it
Back to Atom Neo
The language, the benchmarks against CPython, and the download.

A fork of Atom3 by WawaDev. v3.0.0, Quark