Odin Packages
API documentation for the obench library collection.
Search 115 declarations across 1 packages.
obench
obench
Allocation-aware micro-benchmarking for Odin. It measures time and heap and temp allocations per operation, and compares runs against a saved baseline. It uses only base: and core: packages.
Status: before 1.0. The API and the JSON report layout can still change, and the release notes list every breaking change.
Guide
The package documentation covers the annotations, destructive and multi-threaded benchmarks, running from your own main or inside odin test, reading the report, configuration, and the known limits. obench help lists the CLI options.
Getting Started
obench needs Odin dev-2026-10 or newer. CI tests it on Linux (x86 and ARM), macOS (ARM and Intel), and Windows against the latest Odin release and the nightly build.
-
Copy the
obenchfolder of this repository into your project, for example aslibs/obench. Each release has it asobench-<tag>-library.tar.gzand.zip, together with the license. -
Create a benchmark file such as
bench/append_bench.odin. A benchmark is a procedure namedbench_<name>that takes a^obench.Bencher, and only the body of thesteploop is timed and counted:package append_bench import obench "../libs/obench" // @params(16, 256, 4096) bench_append__grow :: proc(b: ^obench.Bencher) { n := obench.param(b) for obench.step(b) { values: [dynamic]int for i in 0 ..< n { append(&values, i) } obench.keep_alive(&values) delete(values) } } // @params(16, 256, 4096) bench_append__reserve :: proc(b: ^obench.Bencher) { n := obench.param(b) for obench.step(b) { values := make([dynamic]int, 0, n) for i in 0 ..< n { append(&values, i) } obench.keep_alive(&values) delete(values) } } -
Build the CLI from a clone of this repository (on Windows, use
-out:bin/obench.exe), or take a prebuilt one from a release (it still needsodinonPATH), and run it on your project:odin build cmd/obench -out:bin/obench -o:speed ./bin/obench path/to/projectOn an Apple M2:
obench: append_bench (darwin/arm64, -o:Speed, timer overhead 28.5 ns, resolution 41.0 ns) ────────────────────────────────────────────────────────────────────────────────────────────────── benchmark │ fastest │ median(p50) │ p99 │ allocs / bytes │ distribution & notes ────────────────────────────────────────────────────────────────────────────────────────────────── append ├─ grow[16] │ 77.41 ns │ 78.29 ns │ 82.36 ns │ 2.0 / 128 B │ █▆▁▂ ▂▂▁ ├─ reserve[16] │ 35.49 ns │ 38.04 ns │ 43.22 ns │ 1.0 / 128 B │ ▅█▅▄▄▃▁▁ 2.06x faster ├─ grow[256] │ 540.42 ns │ 545.34 ns │ 579.68 ns │ 6.0 / 2.00 KiB │ █▂▂▁▁ ▁ ├─ reserve[256] │ 232.38 ns │ 239.52 ns │ 305.09 ns │ 1.0 / 2.00 KiB │ █▃▁▁ ▁ 2.28x faster ├─ grow[4096] │ 4.68 us │ 4.80 us │ 5.42 us │ 10.0 / 32.00 KiB │ ██▂▂▁▁▁▁ ╰─ reserve[4096] │ 3.32 us │ 3.39 us │ 3.54 us │ 1.0 / 32.00 KiB │ █▂▄▃▂▁▁▂ 1.42x faster ∷ complexity grow → O(N) (R²=0.999, NRMSE=4.4%) ∷ complexity reserve → O(N) (R²=1.000, NRMSE=0.2%) ────────────────────────────────────────────────────────────────────────────────────────────────── PASS: 6 benchmark(s) completed │ geomean: 430.06 nsallocs / bytescounts allocator calls that obtain memory, so the resizes of the growing array show up next to the single allocation of the reserved one.
Checking benchmarks in CI
Save a baseline on one branch and compare another branch against it. --fail-on-regression exits with status 1 when a benchmark got significantly slower:
obench --save-baseline main.json
# ...switch branches...
obench --baseline main.json --fail-on-regression
A change counts as a regression when the Mann-Whitney U test on the samples of both runs finds a difference at the 5% level and the median moved by more than --threshold percent (2% by default). Shared CI runners are noisy, so a real change can still drown in their noise. For a gate, raise the sample count with -n or run it on a dedicated machine.
Benchmarks can also run inside odin test: run_test runs a suite from a @(test) procedure and fails the test on a misused benchmark, a failed @zero_alloc check, or a regression.
Examples
Example benchmarks are in examples. Run them locally with:
git clone https://github.com/zeybek/obench
cd obench
make bench
examples/core_style runs inside odin test and measures core:strings.prefix_length, the same thing as Odin's own tests/benchmark/strings.
License
BSD 3-Clause, see LICENSE.