Very fast
Programs written in Nikaia run in the league of the fastest languages there are. This is where that comes from, and how it is measured.
Four things that make Nikaia programs fast, and what each of them does and does not promise.
1BRC study: the Nikaia compiler vs. human vs. AI
The study sets Nikaia's programs for the One Billion Row Challenge against Rust written by people and by an AI assistant.
It shows how well the compiler optimises a plain program on its own, what hand-tuned Nikaia reaches today, safe and unsafe, and where the journey goes. Along the way it shows what Rust can do, who is ahead, and which tricks the fastest programs use: searching sixteen bytes at once, a name read as two words, a temperature without a branch, checks proved instead of made. And how Nikaia lets a program use each of them, most without unsafe.
106 / 131
instructions per row at x86-64: safe Nikaia / the fastest Rust written by a person
0.14 / 0.47
mispredicted branches per row: safe Nikaia / the same Rust program
One core or all of them
Code written for one core usually has to be rewritten, or at least re-checked, to use several.
What Nikaia checks. The choice is one line in nikaia.toml: user-parallelism = "no" (the default) or "yes". At no, two pieces of your code are never running at the same moment. At yes, a multi-threaded runtime spreads the work over the cores, and thread safety is checked at compile time. A library built at no is still checked against the rules parallel code needs, so it also works when a program built at yes uses it.
The limit. The setting allows parallelism; it does not set a thread count. How many threads serve yes is the runtime’s choice, because it depends on the machine. At no, only your own code is limited to one thread: waiting for I/O happens on the runtime’s own threads, and the standard library may still use every core.
[build]
user-parallelism = "no" # or "yes"No garbage collector, no free
A garbage collector pauses your program at moments you do not choose. Freeing memory by hand hands you the bugs.
What Nikaia checks. Nikaia has no garbage collector and no free. Memory is released at a point you can see in the code, so there are no collector pauses. The compiler works out which data needs protecting and when memory can be freed.
The limit. Nikaia turns your program into a Rust crate, and Rust’s compiler checks memory safety again. So release follows Rust’s rules underneath, and an error from that last step is reported against your .nika line.
You write no free and no lifetimes. The compiler works out when memory can be released, and the release is a point you can see.
Checks that are proved are dropped
Safety checks cost time: an index check on every access, an overflow check on every +.
What Nikaia checks. Nikaia keeps the checks, and drops one only where it has proved it cannot fail. remove-bounds-checks:on writes an index without its check where the compiler has proved 0 <= i < xs.len(). remove-overflow-checks:on does the same for a +, - or * whose result stays inside its type. A check that is not proved is not dropped.
The limit. Both are off by default: you ask for them in nikaia.toml. What is proved does not depend on them; they only choose what is written.
[build]
optimization = "remove-bounds-checks:on,remove-overflow-checks:on"