Performance¶
go-ruby-csv/csv is the pure-Go (CGO-free) library that rbgo binds for Ruby's csv. This
page records real measured benchmarks of the library against the reference
Ruby runtimes — no estimates, no placeholders.
Library-level benchmark (Go API vs runtimes) — 2026-07-03¶
This section measures the pure-Go library directly, through its Go API — not
the rbgo interpreter. It isolates the library primitive
from Ruby-interpreter dispatch, answering the parity question head-on: is the
pure-Go implementation as fast as the reference runtime's own csv? The
same workload, same inputs, same iteration counts run through the Go library
and through each reference runtime's stdlib; outputs were checked identical to
MRI before any timing.
- Host: Apple M4 Max (
Mac16,5, arm64), macOS 26.5.1 — date 2026-07-03. - Runtimes: Go 1.26.4 · MRI
ruby 4.0.5 +PRISM· MRI + YJIT · JRuby 10.1.0.0 (OpenJDK 25) · TruffleRuby 34.0.1 (GraalVM CE Native). - Method: each process runs 3 untimed warm-up passes, then 25 timed passes of
a fixed inner loop, timed with a monotonic clock; the best pass is reported
as ns/op (lower is better).
vs MRI< 1.00× means faster than MRI. Interpreter start-up is outside the timed region, so these are operation costs, notruby file.rbprocess costs.
generate-200x6¶
| Runtime | ns/op | vs MRI |
|---|---|---|
| go-ruby (pure Go) | 40826.8 | 0.19× |
| MRI | 218082.0 | 1.00× |
| MRI + YJIT | 106010.0 | 0.49× |
| JRuby | 90318.4 | 0.41× |
| TruffleRuby | 35323.4 | 0.16× |
parse-200x6¶
| Runtime | ns/op | vs MRI |
|---|---|---|
| go-ruby (pure Go) | 76053.2 | 0.26× |
| MRI | 292822.0 | 1.00× |
| MRI + YJIT | 176362.0 | 0.60× |
| JRuby | 1780914.8 | 6.08× |
| TruffleRuby | 1068829.3 | 3.65× |
The pure-Go library is ~4–5× faster than MRI on both parse (0.26×) and generate (0.19×). MRI's csv is implemented in Ruby, so a compiled pure-Go parser/generator wins outright; TruffleRuby is competitive on generate but its cold parse loop is an outlier.
Reproduce
The harness is committed under
benchmarks/:
a self-contained Go driver (go/, pins the published library via
go.mod), the equivalent ruby/csv.rb workload, and run.sh. Run
bash benchmarks/run.sh; env OUTER/WARM tune the pass budget and
RUBY/JRUBY/TRUFFLERUBY select the runtime binaries.
Warm-up budget & noise — honest framing
Numbers reflect a fixed warm-process budget (3 warm-up + 25 timed passes in one process). The JVM/GraalVM JITs (JRuby, TruffleRuby) may need a larger warm-up to reach steady state, so their columns can understate peak throughput — most visibly TruffleRuby on the shortest loops (a few cold-JIT outliers are noted in the text). Sub-microsecond rows carry the most relative noise; treat those ratios as order-of-magnitude. Every number here is a real measured value from the dated run above — nothing is fabricated, estimated, or cherry-picked. The go-ruby column is the pure-Go library; every other column is that interpreter's own stdlib doing the equivalent work.