Experiment, updated 1 November 2026

Bend to Odin

This project translates programs from a new language, Bend, into Odin, a simple language with direct control of memory. The goal is the same answers at the same speed or better.

8 of 16programs match or beat the best C time
16 of 16benchmarks give C's answer
653 of 653supported test programs pass
  1. The idea
  2. The race
  3. One core against C
  4. Memory without a cleaner
  5. Three languages
  6. What we learned
  7. Right answers
  8. What comes next

The idea

Bend lets a programmer write down what a program must do, then have the computer prove that the program does it. That is very useful when an AI writes the code, because you do not have to trust the AI. Few teams use Bend today. This project gives those proofs to teams that use Odin.

Bend normally turns programs into C. It can also run them on a graphics card. So Odin has to compete with the best of both.

A processor is like a few expert chefs. A graphics card is like thousands of helpers who are fast only when they all do the same step together. Some jobs suit the chefs. Other jobs suit the helpers. The score below always compares with the faster of C on the processor and C on the graphics card.

Odin has no cleaner that stops the program to free memory. This suits Bend programs, which make millions of small objects. The translator cannot use the graphics card yet, so programs that suit the card are behind. That work is in progress.

The race, program by program

Each row is one test program. Further left is faster, and the scale is logarithmic because the times differ by up to 30 times. The ring shows the best C time. The filled dot shows Odin. Hover over a row to see all the times.

Run time on all 16 threads, Odin against best C

Odin and C on the processor ran in turn, with a 3-second rest. Each time is the best of 2 runs. C on the card comes from the Go table run just before. Odin uses the processor only. Bitonic is very close. Another job used up to 2 threads.

See all the times as a table
ProgramC 1Odin 1Odin 2C 2C card
bfs0.590.690.650.660.65
editdist0.480.330.340.450.40
gameoflife2.092.242.222.140.22
hashmap0.510.180.200.500.73
kmeans1.290.690.661.280.58
lexer0.550.490.430.521.25
mandelbrot0.550.540.560.560.19
merkle0.620.660.680.630.20
nbody0.560.630.650.560.20
queens1.541.381.291.751.46
raytrace1.241.271.401.201.20
symreg0.510.330.420.570.51
terrain0.470.520.520.470.36
bitonic2.611.611.542.741.56
matmul0.760.290.260.780.53
radix1.020.570.571.010.71

One core against C

A fair test of the translated code removes parallel work and the card. On one processor core, Odin uses fewer cycles than Bend's C on 13 of 16 programs. On merkle, raytrace and terrain, the difference is 1.5% or less, which is inside the noise.

Processor cycles on one core, Odin as a share of C

Under 100% means that Odin uses less work than C. Billions of user cycles on an Intel i7-10700.

Memory without a cleaner

Each worker takes boxes from its own tray of memory. This needs no lock. When nothing else can read a box, the program gives it back for the next use.

Odin normally passes a hidden context with an allocator to each function. On our test, that path was 7.6 times slower than a private tray, so generated code turns it off.

Build a tree of 8 million nodes

One thread. The standard path makes an indirect call and clears memory for each node.

The translator splits work into a tree of tasks, as in the diagram.

Three languages, side by side

Each cell shows how a language compares with the best C time for that program. Blue is faster than C. Red is slower. A plain number means times faster, and a minus sign means times slower. Go uses the graphics card where the translator can. Zig and Odin use the processor only so far.

Speed against best C

Each lane uses the best C time from its own run. C on the graphics card comes from the Go run for Zig and Odin. Another job used up to 2 threads during these runs.

What we learned

Many numbers at once

The translator can rewrite a suitable loop to process 8 numbers in one step. So far this applies to kmeans only. It cut that program from 24.2 to about 18 billion cycles. The program then needs a processor with AVX2.

Flags that did not help

The most aggressive optimizer setting gave no gain. Tuning for the exact processor made nbody 12% slower.

A bug for everyone

Bend's compiler lost a mark that says a value has more than one reader. Hashmap hung until we kept the mark. The same bug gave wrong answers in Go, and that bug is now fixed there too.

Odd characters work

The Go version stops on characters outside Unicode. Odin keeps any 32-bit character. These tests pass here.

Does it give the right answers?

Test programs that pass

396 more programs are refused because they are outside what the translator supports.

A law check is a rule that the code must obey. We broke a function on purpose to prove that a law check can fail.

What comes next

Honest limits

Words used on this page
Processor (CPU)
The main chip in a computer. It has a few powerful workers.
Graphics card, or card (GPU)
A chip with thousands of simple workers.
Thread
One worker on the processor. This processor has 8 cores and 16 threads.
Cleaner (garbage collector)
The part of Go that finds and frees memory that a program no longer needs. Zig and Odin do not have one.
Box and node
A small piece of memory that holds part of a tree.
Cache miss
A read of data that is not near the processor. It can take 100 times longer than a read of nearby data.
Law check
A rule from the Bend program that the translated code must obey.