Files
benchmarks/framework/zip/record/nosonic.go
zeekay 5afa0b2829 bench(zip): JSON-skip axis — native-ZAP-typed RPC vs HTTP+JSON serde
Separate, orthogonal axis from the zaphttp framing-CPU test (that carries the
body opaque and never touches JSON). Isolates ZAP's real structural win: typed
binary fields read zero-copy (no scan/reflect/per-field alloc) vs HTTP+JSON
(de)serializing text every call. One eth-style record, same compute, same field
set both sides; JSON held to its fastest libs (goccy, sonic) + stdlib.

New shared `record` package (DRY: one record + codecs used by the microbench,
the /rpc server, and the ZAP load generator). serde_test.go: decode/encode/
round-trip/handler benches + wire sizes + round-trip equivalence. main.go: POST
/rpc route (zap transport = zero-copy decode; http transport = JSON codec).
zapload: -scenario rpc sends the identical ZAP-typed body.

Numbers (GB10 arm64, go1.26, median of 3, default GOGC/GOMAXPROCS):
- Decode: ZAP 13.4ns/0-alloc vs goccy 473ns/4, sonic 845ns/8, stdlib 2334ns/13
  (35–174x, 0 vs many allocs) — the crush.
- Encode: honest wash — ZAP 629ns/12-alloc vs goccy 424ns/4 (v1.3.0 SetBytes
  defers tail via copy + offsets slice; SetBytesFixed is luxfi/zap-only).
- Round trip: ZAP 648ns vs goccy 904 / sonic 1509 / stdlib 3107.
- Handler (per-req): ZAP 271ns/5-alloc vs goccy 431/4, sonic 736/7, stdlib 1444/9.
- Wire: total ZAP 162B vs JSON 233B.
- End-to-end /rpc c125 d6s: ZAP 534,945 rps vs sonic 483k (1.11x), goccy 452k
  (1.18x), stdlib 407k (1.31x).

Reproducible off published tags (zap-proto/go v1.3.0, no local replaces).
2026-07-17 10:46:10 -07:00

20 lines
589 B
Go

//go:build !((amd64 || arm64) && !nosonic)
// Fallback when sonic's asm backend is unavailable for this arch (or disabled
// via -tags nosonic): the sonic row is reported as unavailable, never faked.
package record
var SonicAvailable = false
var CodecSonic = JSONCodec{
Name: "sonic",
Marshal: func(v any) ([]byte, error) { return nil, errSonicUnavailable },
Unmarshal: func(b []byte, v any) error { return errSonicUnavailable },
}
var errSonicUnavailable = errSonic{}
type errSonic struct{}
func (errSonic) Error() string { return "sonic unavailable on this arch/build" }