Every number below is real, best-of-5 wall-clock from the cross-runtime suite — no estimates, no extrapolation. Where a runtime can't load a module it shows n/a. rbgo beats MRI on 9 of these standard-library modules outright (and is honest about the two where it loses).
Best-of-5 wall-clock, ms. Apple M-series · ruby 4.0.5 +PRISM (MRI & --yjit) · jruby 10.1.0.0 (OpenJDK 25) · truffleruby 34.0.1 (GraalVM CE Native) · rbgo @ 2026-06-30. Lower is better; ×MRI = rbgo ÷ MRI (<1 means rbgo is faster). Rows where rbgo beats MRI are marked ✓.
| Module | rbgo | MRI | YJIT | JRuby | Truffle | ×MRI |
|---|---|---|---|---|---|---|
| set | 2220 | 220 | 220 | 1240 | 420 | 10.1× |
| prime | 50 | 30 | 50 | 1230 | 190 | 1.7× |
| matrix | 20 | 50 | 50 | 1230 | 210 | 0.40× |
| complex | 100 | 80 | 70 | 1100 | 90 | 1.25× |
| rational | 90 | 50 | 40 | 1090 | 100 | 1.8× |
| cmath | 40 | 60 | 60 | n/a | n/a | 0.67× |
| tsort | 80 | 90 | 80 | 1220 | 250 | 0.89× |
| abbrev | 290 | 220 | 180 | 1330 | 380 | 1.32× |
| did-you-mean | 40 | 1450 | 400 | 2660 | 480 | 0.03× |
| prettyprint | 80 | 90 | 70 | 1380 | 220 | 0.89× |
| scanf | 150 | 570 | 550 | n/a | n/a | 0.26× |
| unicode-normalize | 110 | 370 | 370 | 1380 | 320 | 0.30× |
| cgi | 60 | 60 | 60 | 1090 | 1950 | 1.00× |
| zlib | 360 | 60 | 60 | 1220 | 380 | 6.0× |
| ipaddr | 210 | 110 | 90 | 1600 | 350 | 1.9× |
| pathname | 260 | 440 | 420 | 1890 | 740 | 0.59× |
| rexml | 20 | 510 | 310 | 2850 | 1490 | 0.04× |
cmath / scanf are not bundled in JRuby 10.1 / TruffleRuby 34 (LoadError) → n/a. rbgo beats MRI on did-you-mean (~33×), rexml (~25×), scanf (~4×), unicode-normalize (~3×), matrix (2.5×), pathname (1.7×), cmath (1.5×) and tsort / prettyprint (~1.1×). It honestly loses two: zlib 6× (pure-Go flate vs C-zlib) and set 10× (per-element interpreter dispatch).
rbgo's ahead-of-time backend compiles hot methods to unboxed Go kernels. Against MRI with YJIT enabled, on tight loop / fib kernels:
rbgo+AOT beats MRI with YJIT enabled by 18–24× on loop / fib — unboxed int64 kernels, no boxing on the hot path.
Interned small integers drop a small-int loop from ~245,000 allocations to 1 — the hot integers are shared, immutable singletons.
Capture-tracked frame recycling is ≈14% faster on fib; frames are reused unless a closure captures them. Plus inline method caches on every call site.
The pure-Go front-end and runtime, tested against real-world Ruby applications — parse, parse + compile, and end-to-end execution.
~100% of all valid Ruby parsed across Rails + Puppet — 99.96% of files; the 2 misses are syntax-error fixtures MRI itself rejects.
puppet apply CLIThe genuine puppet apply CLI runs end-to-end on a CGO=0 rbgo:
CommandLine → Apply path converges notify / file / exec resources.exec runs via pure-Go process exec with onlyif / unless / creates / path guards.Per-module cross-runtime application benchmarks beyond the front-end conformance suite are in progress.
← Back to overview