Rust developers seeking to perform precise microbenchmarks often find that standard tools like Criterion lack specific features common in the Go ecosystem. Specifically, Criterion does not natively track heap allocations (B/op), lacks standard pprof profiling integration, and uses a linear-ramp sampling model that can introduce variance and overhead in microsecond-level loops. These limitations make it difficult to perform direct A/B comparisons between Rust and Go implementations or to track memory churn regressions across different commits.

To bridge this gap, Bartek Płotka developed benchfmt.rs, a zero-dependency Rust benchmark runner and a Criterion converter. The tool mimics the Go `testing.B` framework by providing a thread-local heap allocation counter (CountingAlloc) and pprof profiler integration. It supports `/key=value` sub-benchmark naming, which allows the Go-based `benchstat` tool to pivot across different dimensions, such as language or sample size. For existing projects, a converter can take Criterion output and emit the Go-compatible `benchfmt` format, enabling the use of `benchstat` for outlier-resistant median calculations and Mann-Whitney U tests.

A promotional graphic for the benchfmt.rs project showcasing its integration with the Go benchmarking workflow.
The benchfmt.rs project aims to bring Go-style benchmarking telemetry to the Rust ecosystem.www.bwplotka.dev

This image serves as the primary visual for the benchfmt.rs tool, which replicates the Go benchmarking ecosystem for Rust developers.

The tool offers different paths depending on the user's needs. The `benchfmt::Suite` runner is intended for new microbenchmarks where precise heap and profile data are required, as it captures scoped `-cpuprofile` and `-memprofile` files. Conversely, the `benchfmt` CLI converter is best for repositories that already use Criterion and simply need to generate `benchstat` tables without modifying the underlying benchmark code. While Criterion remains the standard for built-in HTML and SVG plots, benchfmt.rs provides the specific telemetry—such as per-operation heap bytes and allocation counts—necessary for high-fidelity performance engineering.

One technical distinction is the sampling model. Criterion defaults to 100 linear-ramp samples, which can inflate variance and add timing overhead. In contrast, benchfmt.rs mimics Go's steady-state epochs, where a fixed iteration count is calibrated for a specific time window (e.g., 2 seconds) and repeated across independent runs. This provides more reliable results for very fast operations where timer-overhead intercepts would otherwise skew the results. However, because the converter approximates these epochs by bucketing Criterion's sample array, the results are an approximation of the steady-state model rather than a perfect replication of Go's internal runtime behavior.