N-body solar system
50,000 integration steps of the outer solar system (Sun + Jupiter, Saturn, Uranus, Neptune) using the canonical Computer Language Benchmarks Game initial conditions. Hot loop is struct-field access through a slice under FP load.
Runtime · median per inner-loop window
Full statistics
| Runner | N | Compile | Runtime | P95 | Stddev | RSS | vs pipit | Status |
|---|---|---|---|---|---|---|---|---|
| Native Gocompiled | 7 | 110 ms | 8.13 ms | 8.27 ms | 48.7 µs | 1.62 GiB | 0.04× | OK |
| Pipitbytecode VM | 7 | 1.83 ms | 207 ms | 210 ms | 1.62 ms | 592 MiB | 1.00× | OK |
| CPython 3.14bytecode VM | 7 | 563 µs | 419 ms | 424 ms | 3.35 ms | n/a | 2.02× | OK |
| PyPy 7.3tracing JIT | 7 | 433 µs | 26.9 ms | 28.3 ms | 648 µs | n/a | 0.13× | OK |
| tengobytecode VM | 7 | 413 µs | 1.09 s | 1.20 s | 49.1 ms | 1.69 GiB | 5.26× | OK |
| scriggobytecode VM | 7 | 769 µs | 941 ms | 991 ms | 20.0 ms | 1.69 GiB | 4.54× | OK |
| mvmbytecode VM | 7 | 727 µs | 953 ms | 964 ms | 8.56 ms | 1.69 GiB | 4.60× | OK |
| yaegiAST walker | 7 | 691 µs | 1.17 s | 1.21 s | 24.8 ms | 1.69 GiB | 5.63× | OK |
Workload & symmetry rules
Workload
Gravitational simulation of five bodies (Sun, Jupiter, Saturn, Uranus, Neptune) over 50,000 time steps. Each step computes pair-wise gravitational impulses for every (i, j) pair, then integrates positions from velocities. Output is the conserved energy before and after, each multiplied by 1e9 and rounded to integer.
Symmetry rules
- Bodies are stored as a slice of records with named fields (
Bodystruct on Go, class with__slots__on Python). The hot loop pays struct-field-access cost on every runner. - Tengo has no struct type, so its translation uses parallel arrays (struct-of-arrays) over the seven body fields. Shape of the hot loop is otherwise identical.
math.Sqrt/math.sqrtis the only stdlib intrinsic allowed; sqrt is implemented identically (libm) across every runner so its cost does not distort the comparison.
Banned
- Numpy, scipy, gonum, hand-written assembly, any SIMD shortcut.
- Threading or process parallelism. This benchmark is single-threaded serial throughput by design (bench 16 covers parallelism).
Why this benchmark exists
The unique signal: struct field access inside an FP hot loop. Bench 14 uses four local scalar floats and no struct. Bench 21 uses 2D float arrays. Neither stresses the struct path. pipit's struct-in-typed-slice path is the open Phase 7 (struct unboxing) area; this benchmark gives a clean before-after measurement of any work on that path.
Source code
pipit / Go
pipit_source.gonative Go
native_main.goCPython / PyPy
cpython.pytengo
script.tengo