Open-source project
nvzqz/divan avatar
nvzqz/divan

Divan for Rust: Simple Benchmarking with cargo bench

Fast and simple benchmarking for Rust projects

1,464 stars43 forksRustApache-2.0

At a glance

What is it?
Divan is a Rust benchmarking library for developers who want a compact benchmark harness, configurable cases, statistical output, and CI checks without adopting a larger benchmarking suite. It uses Rust `0.80.0` or later and disables Cargo's default benchmark harness for registered benchmarks.
Who is it for?
Adopt Divan when a Rust project needs a lightweight, source-local benchmark harness and can accept its small documented feature surface. Do not choose it when you require undocumented statistical controls, advanced benchmark scenarios, or a large result database.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 111 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • nvzqz/divan1,464 ★ · +6
Star history
Repository2026-10-162026-11-07
nvzqz/divan1.5k1.5k

6 Stars in the last 22 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Why Divan Exists in a Rust Crate

Divan addresses the recurring need to measure small pieces of Rust code without turning benchmark setup into a separate service or administration task. Its audience is Rust developers working on library functions, algorithms, parsers, allocation-sensitive code, or any other path where a timing regression matters. The project presents itself as "Comfy benchmarking for Rust projects," and the repository describes it as a "Statistically-comfy benchmarking library."

The basic workflow is intentionally close to Cargo. A crate adds Divan as a development dependency, declares a benchmark in `Cargo.toml`, writes benchmark functions in `benches/example.rs`, and runs `cargo bench`. The benchmark attribute registers functions and accepts case values through `args`. That design makes Divan suitable for projects that want benchmark source to live beside the code it measures, rather than for teams seeking a hosted or distributed benchmarking platform.

Divan does not attempt to replace every kind of performance analysis. The README focuses on benchmark registration, repeated samples, summary statistics, and a test mode for CI. It does not document CPU pinning, hardware control, statistical significance tests, flame graphs, or a persistent comparison database. Those omissions matter when deciding whether the library matches a performance engineering process rather than just a convenient local measurement loop.

Divan's Custom Cargo Benchmark Harness

The integration point is the benchmark entry point. The `Cargo.toml` setting `harness = false` tells Cargo not to use its default benchmark harness for the named target. The benchmark file then defines `main`, and that function calls `divan::main()`. At the same time, `#[divan::bench(args = [1, 2, 4, 8, 16, 32])]` registers a function named `fibonacci` and asks Divan to run it for several input values.

The example returns a number from the benchmarked function. That matters because Divan can keep the result in the benchmark path while still reporting timing data, although the README does not provide a separate mechanism for checking return values. The runner collects measurements across registered cases and prints a table containing fastest, slowest, median, mean, samples, and iterations. The sample table shows both nanoseconds and microseconds, then milliseconds as the workload becomes larger.

The dependency list includes `clap`, so the project has a command-line argument layer, and it includes the `divan-macros` crate for benchmark registration. The repository also has separate `macros/` and `internal_benches/` directories, indicating that registration and internal benchmark behavior are split from the main crate layout. The README points to `#[divan::bench]` documentation for more extensive examples, but it does not document every filtering, sampling, or reporting option there.

Installing Divan and Running the Fibonacci Example

Divan `0.1.21` requires Rust `1.80.0` or later. Add the dependency and benchmark target to the project's `Cargo.toml`:

toml
[dev-dependencies]
divan = "0.1.21"

[[bench]]
name = "example"
harness = false

Create `benches/example.rs` inside the crate directory. The example registers one benchmark across six input sizes:

rust
fn main() {
    divan::main();
}

#[divan::bench(args = [1, 2, 4, 8, 16, 32])]
fn fibonacci(n: u64) -> u64 {
    if n <= 1 {
        1
    } else {
        fibonacci(n - 2) + fibonacci(n - 1)
    }
}

Run the benchmark with:

sh
cargo bench

The documented output contains a case row for each value in `args`, along with timing statistics and iteration counts. For CI, the README offers a mode that runs each benchmarked function once to check that it does not panic without measuring performance:

sh
cargo bench -- --test

The alternative documented command is:

sh
cargo test --benches

These commands distinguish a normal performance run from a panic-oriented CI check. The README does not explain how to compare results between commits, so this setup alone is not a complete regression gate.

What the Benchmark Table Does and Does Not Establish

Divan's default table gives a useful first view of measured behavior. It reports the fastest, slowest, median, mean, sample count, and iteration count for every registered case. That is enough to see whether a benchmark is running, whether larger inputs behave differently, and whether results fluctuate within a run. The Fibonacci example also shows that the table is hierarchical, with the benchmark name followed by individual argument values.

Those statistics should not be treated as a complete explanation of performance. The README does not state whether results are normalized across machines, whether benchmarks are randomized, or how Divan chooses its sample count and iteration count. It also does not document confidence intervals, standard deviation, outlier handling, or comparison thresholds. Therefore, a change from one local run to another should be interpreted cautiously, especially when the code runs on different hardware.

The `--test` command has a narrower purpose. According to the README, it runs each benchmarked function once to check that the functions do not panic. It is useful as a fast correctness smoke check, but it deliberately does not provide performance measurements. A project can therefore use both modes, although the repository does not prescribe a complete CI policy for detecting regressions.

Limitations for Long-Lived Rust Projects

The clearest limitation is the size of the documented surface. Divan covers registration, argument cases, output statistics, and test-mode execution, but the README does not cover a persistent baseline, machine metadata, threshold configuration, or report export. A team whose performance workflow depends on those features may find the basic runner insufficient.

There is also a compatibility consequence in `harness = false`. Once Cargo's default harness is disabled for the target, the project owns the benchmark entry point and its integration expectations. The example demonstrates the required shape, but it does not document migration guidance for projects with existing benchmark targets. The repository has no GitHub releases listed, so upgrade planning cannot rely on a release cadence visible in the repository metadata.

The library supports a `dyn_thread_local` feature described in `Cargo.toml` as an opt-out from faster static thread-local access. That exposes a low-level choice, but the README does not explain which workloads should select it. Its presence shows that Divan pays attention to runtime access patterns, yet it is not enough on its own to predict application performance.

Finally, benchmarking only measures the cases supplied by the author. The Fibonacci example uses six inputs, but there is no documentation here for setup and teardown exclusion, asynchronous workloads, external I/O, or controlled fixture construction. Those workloads need their own benchmark design, and Divan should not be assumed to isolate them automatically.

Divan Compared with Cargo's Default Benchmark Harness

The relevant alternative visible in the repository is Cargo's default benchmark harness. Divan's configuration explicitly sets `harness = false`, and the benchmark file supplies its own `main` function that calls `divan::main()`. That is the concrete architectural difference: Divan supplies a custom Rust benchmark runner, while Cargo's default harness remains available for targets that do not disable it.

The repository's `keywords` list includes `criterion`, indicating that Divan is positioned alongside Rust benchmarking tools in search metadata. However, the README does not describe Criterion's behavior, configuration, or results format, so it would be inaccurate to claim a detailed comparison with that crate. The only verified comparison here is the Cargo integration point and the custom Divan entry point.

For a small crate, the Divan route keeps the setup compact: one development dependency, one benchmark target, one Rust file, and `cargo bench`. A project that already depends on a different benchmark runner should first compare its required reporting and CI controls. Divan's documentation is strongest for the basic registered-function workflow, not for feature-by-feature evaluation of alternative tools.

Maintenance, License, and Upgrade Boundaries

The repository is not archived. Its last push was on 2026-07-19, which is within the six-month period relevant to maintenance classification. That supports describing the repository as recently changed, but the repository has no GitHub releases, so there is no visible release history in the metadata for assessing upgrade frequency or stability. The version in `Cargo.toml` is `0.1.21`, and the README states that this version requires Rust `1.80.0` or later.

Divan is licensed under either MIT or Apache-2.0, as stated in the `Cargo.toml` and README. A project must follow the license terms that apply to the chosen distribution and comply with the relevant notices. This is a project-specific licensing summary, not legal advice.

Upgrading involves checking the Rust toolchain requirement, the `divan-macros` version, feature defaults, and the benchmark API documented by the new release. The repository includes `CHANGELOG.md`, so the specific upgrade changes should be checked there. The absence of GitHub releases also means that users should inspect the changelog and crate documentation rather than infer a release history.

Editorial conclusion

Adopt Divan when a Rust project needs a lightweight, source-local benchmark harness and can accept its small documented feature surface. Do not choose it when you require undocumented statistical controls, advanced benchmark scenarios, or a large result database. Verify first that Rust `1.80.0` or later is available, that `harness = false` is compatible with the crate, and that the output produced by `cargo bench -- --test` meets the project's CI expectations.

Frequently asked questions

How do I install and run a Divan benchmark in a Rust project?

Add `divan = "0.1.21"` under `[dev-dependencies]`, declare `[[bench]]` with `harness = false`, create a benchmark file, and run `cargo bench`. Divan `0.1.21` requires Rust `1.80.0` or later.

How does Divan benchmark multiple inputs?

Use the `args` parameter on `#[divan::bench]`. The README example uses `args = [1, 2, 4, 8, 16, 32]`, which registers the function for each listed input value.

Can Divan run benchmarks in CI without measuring performance?

Yes. The README documents `cargo bench -- --test`, which runs each benchmarked function once to check that it does not panic. It also documents `cargo test --benches` as an alternative command.

What performance statistics does Divan print?

The documented table includes fastest, slowest, median, mean, samples, and iterations for each benchmark case. The README does not document confidence intervals, outlier handling, or a baseline comparison feature.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. nvzqz/divan on GitHub
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nvzqz-divan.svg)](https://hysenlabs.com/projects/nvzqz-divan)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/nvzqz-divan.svg)](https://hysenlabs.com/projects/nvzqz-divan)

Was this useful?