microbench

package
v0.1.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package microbench is the schema, `go test -bench` parser, and encoders for the framework-tax microbenchmark (issue #141 §13 A): the per-request abstraction cost of each layer — net/http → Gin → Huma → Gombit — across the five scenarios (plaintext, json, path-param, valid-post, invalid-post), reported as ns/op, B/op, and allocs/op.

Each stack is a separate `go test` process (constructing framework.App mutates a process-global; see benchmarks/micro/gombit), so the parser tags rows with the stack the orchestrator ran, and rows merge by stack (a stack is replaced whole, so a partial re-run can't leave stale scenarios behind). Every `-count` ns/op sample is kept, not just the last, so a statistical summary (median/CoV, benchstat) is a non-breaking addition rather than lost data. Keeping the parse + schema here (not in the shell) lets it be unit-tested against captured `go test -bench` output.

Index

Constants

View Source
const SchemaVersion = 1

SchemaVersion is bumped on any breaking change to the row shape (issue §9).

Variables

View Source
var Scenarios = []string{"plaintext", "json", "path-param", "valid-post", "invalid-post"}

Scenarios is the full set every stack must report; a run missing any of these is incomplete and rejected rather than published as a partial row set.

Functions

func Relative

func Relative(x, base float64) string

Relative renders x/base as a "N.Nx" string (base itself is "1.0x").

func WriteJSON

func WriteJSON(w io.Writer, rows []Row) error

WriteJSON / ReadJSON are the canonical microbench.json encoders.

Types

type Row

type Row struct {
	SchemaVersion int       `json:"schema_version"`
	Stack         string    `json:"stack"`
	Scenario      string    `json:"scenario"`
	NsPerOp       []float64 `json:"ns_per_op"`
	BytesPerOp    int64     `json:"bytes_per_op"`
	AllocsPerOp   int64     `json:"allocs_per_op"`
}

Row is one (stack, scenario) measurement. NsPerOp holds every `-count` sample (so median/variance is derivable and nothing is thrown away); B/op and allocs/op are deterministic for these benchmarks and stored as scalars.

func Merge

func Merge(existing, incoming []Row) []Row

Merge returns existing with every row for the incoming stacks removed and the incoming rows appended — a stack is replaced as a whole, so a re-run can't leave a stale scenario from a previous run. Deterministically sorted.

func ParseBenchOutput

func ParseBenchOutput(stack string, r io.Reader) ([]Row, error)

ParseBenchOutput reads `go test -bench` text output for one stack and returns a row per BenchmarkFrameworkTax/<scenario>, accumulating every iteration's ns/op into NsPerOp. Non-benchmark lines are ignored. It errors unless every scenario in Scenarios is present (a panic mid-run yields fewer scenarios, which must fail rather than publish a partial stack).

func ReadJSON

func ReadJSON(r io.Reader) ([]Row, error)

func (Row) CoVNsPerOp

func (r Row) CoVNsPerOp() float64

CoVNsPerOp is the coefficient of variation (sample stddev / mean) of the ns/op samples — a stability signal. A high value means the run was noisy (a non-stationary series on a contended host), so the median should be distrusted: e.g. a layering-cost inversion (Huma cheaper than the Gin it sits on) is only ever noise. Fewer than two samples or a zero mean → 0.

func (Row) MedianNsPerOp

func (r Row) MedianNsPerOp() float64

MedianNsPerOp is the median of the ns/op samples (0 if none) — the headline statistic, matching the CRUD table's use of the median.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL