### Getting Started with Divan Source: https://docs.rs/divan Instructions on how to add Divan to your project and set up your first benchmark. ```APIDOC ## Getting Started Divan `0.1.21` requires Rust `1.80.0` or later. 1. Add the following to your project’s `Cargo.toml`: ```toml [dev-dependencies] divan = "0.1.21" [[bench]] name = "example" harness = false ``` 2. Create a benchmarks file at `benches/example.rs` with your benchmarking code: ```rust fn main() { // Run registered benchmarks. divan::main(); } // Register a `fibonacci` function and benchmark it over multiple cases. #[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) } } ``` 3. Run your benchmarks with `cargo bench`: ```bash example fastest │ slowest │ median │ mean │ samples │ iters ╰─ fibonacci │ │ │ │ │ ├─ 1 0.626 ns │ 1.735 ns │ 0.657 ns │ 0.672 ns │ 100 │ 819200 ├─ 2 2.767 ns │ 3.154 ns │ 2.788 ns │ 2.851 ns │ 100 │ 204800 ├─ 4 6.816 ns │ 7.671 ns │ 7.061 ns │ 7.167 ns │ 100 │ 102400 ├─ 8 57.31 ns │ 62.51 ns │ 57.96 ns │ 58.55 ns │ 100 │ 12800 ├─ 16 2.874 µs │ 3.812 µs │ 2.916 µs │ 3.006 µs │ 100 │ 200 ╰─ 32 6.267 ms │ 6.954 ms │ 6.283 ms │ 6.344 ms │ 100 │ 100 ``` See `#[divan::bench]` for info on benchmark function registration. ``` -------------------------------- ### Clone and Run Divan Examples Source: https://docs.rs/divan Clone the Divan repository to access and run example benchmarks locally. This command benchmarks all features for the examples. ```bash git clone https://github.com/nvzqz/divan.git cd divan cargo bench -q -p examples --all-features ``` -------------------------------- ### Benchmarking Examples Source: https://docs.rs/divan/0.1.21/divan/index.html Instructions on how to run provided examples and clone the repository for more in-depth exploration. ```APIDOC ## Running Examples To run practical example benchmarks: 1. **Clone the repository**: ```bash git clone https://github.com/nvzqz/divan.git cd divan ``` 2. **Run benchmarks for examples**: ```bash cargo bench -q -p examples --all-features ``` More usage examples can be found in the `#[divan::bench]` documentation. ``` -------------------------------- ### Running Example Benchmarks Source: https://docs.rs/divan Instructions on how to clone the Divan repository and run the example benchmarks. ```APIDOC ### §Examples Practical example benchmarks can be found in the `examples/benches` directory. These can be benchmarked locally by running: ```bash git clone https://github.com/nvzqz/divan.git cd divan cargo bench -q -p examples --all-features ``` More thorough usage examples can be found in the `#[divan::bench]` documentation. ``` -------------------------------- ### Benchmark Output Example Source: https://docs.rs/divan/0.1.21/divan/index.html Sample output format displayed after running benchmarks with cargo bench. ```text example fastest │ slowest │ median │ mean │ samples │ iters ╰─ fibonacci │ │ │ │ │ ├─ 1 0.626 ns │ 1.735 ns │ 0.657 ns │ 0.672 ns │ 100 │ 819200 ├─ 2 2.767 ns │ 3.154 ns │ 2.788 ns │ 2.851 ns │ 100 │ 204800 ├─ 4 6.816 ns │ 7.671 ns │ 7.061 ns │ 7.167 ns │ 100 │ 102400 ├─ 8 57.31 ns │ 62.51 ns │ 57.96 ns │ 58.55 ns │ 100 │ 12800 ├─ 16 2.874 µs │ 3.812 µs │ 2.916 µs │ 3.006 µs │ 100 │ 200 ╰─ 32 6.267 ms │ 6.954 ms │ 6.283 ms │ 6.344 ms │ 100 │ 100 ``` -------------------------------- ### Basic Divan Benchmark Setup Source: https://docs.rs/divan Set up a basic benchmark file in `benches/example.rs`. This includes the `main` function to run benchmarks and a sample benchmark function registered with `#[divan::bench]`. ```rust fn main() { // Run registered benchmarks. divan::main(); } // Register a `fibonacci` function and benchmark it over multiple cases. #[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) } } ``` -------------------------------- ### Set up AllocProfiler with System Allocator Source: https://docs.rs/divan/0.1.21/divan/struct.AllocProfiler.html Use this setup to wrap the default System allocator with AllocProfiler for measuring global memory usage. This is the default and recommended approach for most use cases. ```rust use std::collections::* use divan::AllocProfiler; #[global_allocator] static ALLOC: AllocProfiler = AllocProfiler::system(); fn main() { divan::main(); } #[divan::bench(types = [ Vec, LinkedList, HashSet, ])] fn from_iter() -> T where T: FromIterator, { (0..100).collect() } #[divan::bench(types = [ Vec, LinkedList, HashSet, ])] fn drop(bencher: divan::Bencher) where T: FromIterator, { bencher .with_inputs(|| (0..100).collect::()) .bench_values(std::mem::drop); } ``` -------------------------------- ### Benchmark with Counter Source: https://docs.rs/divan/0.1.21/divan/counter/trait.IntoCounter.html Example usage of the counter method within a divan benchmark to track item counts. ```rust #[divan::bench] fn sort_values(bencher: divan::Bencher) { let mut values: Vec = // ... bencher .counter(values.len()) .bench_local(|| { divan::black_box(&mut values).sort(); }); } ``` -------------------------------- ### Benchmark with black_box Source: https://docs.rs/divan/0.1.21/divan/fn.black_box.html An example using black_box to force the compiler to execute the function and treat inputs as unpredictable. ```rust use std::hint::black_box; // Same `contains` function. fn contains(haystack: &[&str], needle: &str) -> bool { haystack.iter().any(|x| x == &needle) } pub fn benchmark() { let haystack = vec!["abc", "def", "ghi", "jkl", "mno"]; let needle = "ghi"; for _ in 0..10 { // Force the compiler to run `contains`, even though it is a pure function whose // results are unused. black_box(contains( // Prevent the compiler from making assumptions about the input. black_box(&haystack), black_box(needle), )); } } ``` -------------------------------- ### Benchmarking with `Bencher` Context Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html When benchmarks require setup or more control, they can accept a `Bencher` argument and use `Bencher::bench_local` for fine-grained timing. ```rust use divan::{Bencher, black_box}; #[divan::bench] fn copy_from_slice(bencher: Bencher) { let src = (0..100).collect::>(); let mut dst = vec![0; src.len()]; bencher.bench_local(move || { black_box(&mut dst).copy_from_slice(black_box(&src)); }); } ``` -------------------------------- ### Benchmark without black_box Source: https://docs.rs/divan/0.1.21/divan/fn.black_box.html An example of a benchmark function susceptible to compiler optimizations that may render the test inaccurate. ```rust fn contains(haystack: &[&str], needle: &str) -> bool { haystack.iter().any(|x| x == &needle) } pub fn benchmark() { let haystack = vec!["abc", "def", "ghi", "jkl", "mno"]; let needle = "ghi"; for _ in 0..10 { contains(&haystack, needle); } } ``` -------------------------------- ### Divan API - `prelude` Module Source: https://docs.rs/divan The `prelude` module provides common items for easy import with `use divan::prelude::*;`. ```APIDOC ## Modules§ prelude `use divan::prelude::*;` to import common items. ``` -------------------------------- ### Initialize Divan from CLI Arguments Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Creates a Divan instance by parsing command-line arguments. Use this to configure benchmarks via the CLI. ```rust pub fn from_args() -> Self ``` -------------------------------- ### Get minimum of two BytesCount values Source: https://docs.rs/divan/0.1.21/divan/counter/struct.BytesCount.html Compares two BytesCount values and returns the minimum. This is part of the Ord trait implementation. ```rust fn min(self, other: Self) -> Self where Self: Sized ``` -------------------------------- ### Get maximum of two BytesCount values Source: https://docs.rs/divan/0.1.21/divan/counter/struct.BytesCount.html Compares two BytesCount values and returns the maximum. This is part of the Ord trait implementation. ```rust fn max(self, other: Self) -> Self where Self: Sized ``` -------------------------------- ### Basic Benchmarking with `#[divan::bench]` Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Use this macro to register a simple benchmarking function. The `main` function must call `divan::main()` to run the benchmarks. ```rust use divan::black_box; #[divan::bench] fn add() -> i32 { black_box(1) + black_box(42) } fn main() { // Run `add` benchmark: divan::main(); } ``` -------------------------------- ### Import Divan Prelude Source: https://docs.rs/divan/0.1.21/divan/prelude/index.html Use this statement to import common items required for benchmarking with Divan. ```rust use divan::prelude::*; ``` -------------------------------- ### Run Divan Benchmarks Source: https://docs.rs/divan Execute your benchmarks using the `cargo bench` command. The output displays performance metrics for each benchmark case. ```bash cargo bench ``` -------------------------------- ### Configure Divan with CLI Arguments Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Applies configuration options by parsing command-line arguments to an existing Divan instance. This can override previous settings. ```rust pub fn config_with_args(self) -> Self ``` -------------------------------- ### Conditionally Ignore Benchmark with Environment Variable Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Benchmarks can be ignored based on runtime conditions, such as the value of an environment variable. This example ignores the benchmark unless the `BENCH_EXPENSIVE` environment variable is set to 'true'. ```rust #[divan::bench( ignore = std::env::var("BENCH_EXPENSIVE").as_deref() != Ok("true") )] fn expensive_bench() { // ... } ``` -------------------------------- ### Perform Configured Action Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Executes the action defined by the Divan configuration. By default, this runs the registered benchmarks. ```rust pub fn main(&self) ``` -------------------------------- ### Basic Benchmarking with Bencher Source: https://docs.rs/divan/0.1.21/divan/struct.Bencher.html Use `Bencher::bench_local` for benchmarking code that runs on the current thread. Ensure necessary imports like `divan::Bencher` and `divan::black_box` are included. ```rust use divan::{Bencher, black_box}; #[divan::bench] fn copy_from_slice(bencher: Bencher) { // Input and output buffers get used in the closure. let src = (0..100).collect::>(); let mut dst = vec![0; src.len()]; bencher.bench_local(|| { black_box(&mut dst).copy_from_slice(black_box(&src)); }); } ``` -------------------------------- ### Run Registered Benchmarks Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Executes all registered benchmark functions. This is the default action when `Divan::main` is called without specific configuration. ```rust pub fn run_benches(&self) ``` -------------------------------- ### Using Bencher::counter Source: https://docs.rs/divan/0.1.21/divan/counter/index.html Demonstrates how to measure throughput by providing a counter to the Bencher instance. ```APIDOC ## Using Bencher::counter ### Description Measures the throughput of a benchmarked function by tracking the number of items processed per iteration using a counter. ### Usage 1. Instantiate a counter (e.g., BytesCount, ItemsCount). 2. Pass the counter to the `bencher.counter()` method. 3. Execute the benchmark using `bencher.bench()`. ### Request Example ```rust use divan::counter::BytesCount; #[divan::bench] fn slice_into_vec(bencher: divan::Bencher) { let ints: &[i32] = &[...]; let bytes = BytesCount::of_slice(ints); bencher .counter(bytes) .bench(|| -> Vec { divan::black_box(ints).into() }); } ``` ``` -------------------------------- ### Execute benchmarks with divan::main Source: https://docs.rs/divan/0.1.21/divan/fn.main.html Use this function to run all benchmarks registered with the #[divan::bench] attribute. ```rust #[divan::bench] fn add() -> i32 { // ... } fn main() { // Run `add` benchmark: divan::main(); } ``` -------------------------------- ### Divan API - `main` Function Source: https://docs.rs/divan The `main` function is used to run all registered benchmarks. ```APIDOC ## Functions§ main Runs all registered benchmarks. ``` -------------------------------- ### AllocProfiler::system Source: https://docs.rs/divan/0.1.21/divan/struct.AllocProfiler.html Creates an AllocProfiler instance that profiles the default System allocator. ```APIDOC ## pub const fn system() -> Self ### Description Profiles the default System allocator. ### Method Static Constructor ### Request Example ```rust #[global_allocator] static ALLOC: AllocProfiler = AllocProfiler::system(); ``` ``` -------------------------------- ### Benchmark Function Registration Source: https://docs.rs/divan/0.1.21/divan/index.html Demonstrates how to register a function for benchmarking using the `#[divan::bench]` attribute macro. ```APIDOC ## `#[divan::bench]` Attribute Macro Registers a benchmarking function. ### Example ```rust #[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) } } ``` This macro allows you to specify arguments for the benchmark function, enabling testing across different input values. ``` -------------------------------- ### Configure shared benchmarking options Source: https://docs.rs/divan/0.1.21/divan/attr.bench_group.html Setting options like sample_count and sample_size that apply to all benchmarks within the module. ```rust #[divan::bench_group( sample_count = 100, sample_size = 500, )] mod math { use divan::black_box; #[divan::bench] fn add() -> i32 { black_box(1) + black_box(42) } #[divan::bench] fn div() -> i32 { black_box(1) / black_box(42) } } fn main() { // Run `math::add` and `math::div` benchmarks: divan::main(); } ``` -------------------------------- ### List Registered Benchmarks Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Prints a list of all registered benchmark functions, mimicking the output of the `--list` flag. ```rust pub fn list_benches(&self) ``` -------------------------------- ### main Function - Run Benchmarks Source: https://docs.rs/divan/0.1.21/divan/fn.main.html The `main` function in the divan library is used to discover and run all registered benchmarks within your project. It's typically called from your application's `main` function after defining benchmarks using the `#[divan::bench]` attribute. ```APIDOC ## main divan # Function main Copy item path Source Search Settings Help ## Summary ```rust pub fn main() ``` ### Description Runs all registered benchmarks. ### Examples ```rust #[divan::bench] fn add() -> i32 { // ... } fn main() { // Run `add` benchmark: divan::main(); } ``` See `#[divan::bench]` for more examples. ``` -------------------------------- ### Core Divan Components Source: https://docs.rs/divan/0.1.21/divan/index.html Overview of key structs and functions provided by the Divan crate. ```APIDOC ## Core Components ### Structs * **`AllocProfiler`**: Measures `GlobalAlloc` memory usage. * **`Bencher`**: Enables contextual benchmarking in `#[divan::bench]`. * **`Divan`**: The benchmark runner. ### Functions * **`black_box`**: Prevents compiler optimizations on a value. * **`black_box_drop`**: `black_box` + `drop` convenience function. * **`main`**: Runs all registered benchmarks. ``` -------------------------------- ### AllocProfiler::new Source: https://docs.rs/divan/0.1.21/divan/struct.AllocProfiler.html Creates an AllocProfiler instance that wraps a custom GlobalAlloc implementation. ```APIDOC ## pub const fn new(alloc: A) -> Self ### Description Profiles a custom GlobalAlloc implementation (e.g., mimalloc). ### Method Static Constructor ### Parameters #### Request Body - **alloc** (A) - Required - The GlobalAlloc implementation to wrap. ### Request Example ```rust use mimalloc::MiMalloc; #[global_allocator] static ALLOC: AllocProfiler = AllocProfiler::new(MiMalloc); ``` ``` -------------------------------- ### Specifying `divan` Crate Path with `crate` Option Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Use the `crate` option to specify the path to the `divan` crate instance when `divan` is used via a macro from your own crate. This is useful for avoiding ambiguity in complex dependency graphs. ```rust extern crate divan as sofa; #[::sofa::bench(crate = ::sofa)] fn add() -> i32 { // ... } ``` -------------------------------- ### Divan Prelude Re-exports Source: https://docs.rs/divan/0.1.21/divan/prelude/index.html This section details the items re-exported by the `divan::prelude::*` import, which are commonly used in Divan benchmarking. ```APIDOC ## Module prelude divan # Module prelude Copy item path Source Search Settings Help Summary Expand description `use divan::prelude::*;` to import common items. ## Re-exports§ `pub use crate::bench;` `pub use crate::bench_group;` `pub use crate::black_box;` `pub use crate::black_box_drop;` `pub use crate::AllocProfiler;` `pub use crate::Bencher;` `pub use crate::Divan;` ``` -------------------------------- ### Divan Execution Methods Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Methods for running, testing, or listing registered benchmark functions. ```APIDOC ## Execution Methods ### Description Methods to trigger the execution of the benchmark suite. ### Methods - **main()**: Performs the configured action (defaults to run_benches). - **run_benches()**: Executes all registered benchmark functions. - **test_benches()**: Runs each benchmarked function once for testing purposes. - **list_benches()**: Prints all registered benchmark functions. ``` -------------------------------- ### Add Divan to Cargo.toml Source: https://docs.rs/divan Add Divan as a development dependency and configure the benchmark harness in your Cargo.toml file. Requires Rust 1.80.0 or later. ```toml [dev-dependencies] divan = "0.1.21" [[bench]] name = "example" harness = false ``` -------------------------------- ### Wrap Custom GlobalAlloc with AllocProfiler Source: https://docs.rs/divan/0.1.21/divan/struct.AllocProfiler.html Wrap other GlobalAlloc implementations, such as mimalloc, with AllocProfiler using `AllocProfiler::new()`. This allows profiling of custom allocators. ```rust use divan::AllocProfiler use mimalloc::MiMalloc; #[global_allocator] static ALLOC: AllocProfiler = AllocProfiler::new(MiMalloc); ``` -------------------------------- ### Divan API - `Bencher` Struct Source: https://docs.rs/divan The `Bencher` struct enables contextual benchmarking in `#[divan::bench]`. ```APIDOC ## Structs§ Bencher Enables contextual benchmarking in `#[divan::bench]`. ``` -------------------------------- ### Divan Configuration API Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Methods for configuring benchmark behavior, including filtering, sampling, and threading options. ```APIDOC ## Configuration Methods ### Description Methods to configure the benchmark runner behavior. ### Configuration Options - **from_args()**: Creates an instance from CLI arguments. - **color(yes: Option)**: Sets output coloring. - **run_ignored()**: Includes benchmarks marked #[ignore]. - **skip_regex(filter: IntoRegex)**: Skips benchmarks matching a regex pattern. - **skip_exact(filter: String)**: Skips benchmarks matching the exact name. - **sample_count(count: u32)**: Sets the number of sampling iterations. - **sample_size(count: u32)**: Sets the number of iterations per sample. - **threads(threads: IntoIterator)**: Configures multi-threaded execution. - **min_time(time: Duration)**: Sets the minimum time floor. - **max_time(time: Duration)**: Sets the maximum time ceiling. ``` -------------------------------- ### Run Only Ignored Benchmarks Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Configures Divan to exclusively run benchmarks marked with the `#[ignore]` attribute. Equivalent to the `--ignored` CLI flag. ```rust pub fn run_only_ignored(self) -> Self ``` -------------------------------- ### Divan Crate API Overview Source: https://docs.rs/divan/0.1.21/divan/all.html This section outlines the main components of the divan crate, including structs, enums, traits, attribute macros, and functions. ```APIDOC ## Divan Crate API Overview This documentation covers the `divan` crate version 0.1.21. ### Structs - `AllocProfiler`: For profiling memory allocations. - `Bencher`: A struct for benchmarking. - `Divan`: The main struct for setting up and running benchmarks. - `counter::BytesCount`: A counter for tracking bytes. - `counter::CharsCount`: A counter for tracking characters. - `counter::CyclesCount`: A counter for tracking CPU cycles. - `counter::ItemsCount`: A counter for tracking items. ### Enums - `counter::BytesFormat`: Enum for formatting byte counts. ### Traits - `counter::Counter`: Trait for counter types. - `counter::IntoCounter`: Trait for types that can be converted into a counter. ### Attribute Macros - `bench`: Macro to define a benchmark function. - `bench_group`: Macro to group related benchmarks. ### Functions - `black_box`: A function to prevent the compiler from optimizing away certain operations. - `black_box_drop`: A function similar to `black_box` but specifically for drop behavior. - `main`: The entry point for the benchmark runner. ``` -------------------------------- ### Specify crate path for macros Source: https://docs.rs/divan/0.1.21/divan/attr.bench_group.html Use the crate option when using Divan via a macro from a different crate instance. ```rust extern crate divan as sofa; #[::sofa::bench_group(crate = ::sofa)] mod math { #[::sofa::bench(crate = ::sofa)] fn add() -> i32 { // ... } } ``` -------------------------------- ### Divan API - `counter` Module Source: https://docs.rs/divan The `counter` module provides functionality to count values processed in each iteration to measure throughput. ```APIDOC ## Modules§ counter Count values processed in each iteration to measure throughput. ``` -------------------------------- ### Divan API - `#[divan::bench]` Attribute Macro Source: https://docs.rs/divan The `#[divan::bench]` attribute macro is used to register benchmarking functions. ```APIDOC ## Attribute Macros§ bench Registers a benchmarking function. ``` -------------------------------- ### Cascade benchmarking options Source: https://docs.rs/divan/0.1.21/divan/attr.bench_group.html Options defined in parent groups are inherited by child groups and benchmarks, but can be overridden. ```rust #[divan::bench_group( sample_count = 100, sample_size = 500, )] mod parent { #[divan::bench_group(sample_size = 1)] mod child1 { #[divan::bench] fn bench() { // Will be sampled 100 times with 1 iteration per sample. } } #[divan::bench_group(sample_count = 42)] mod child2 { #[divan::bench] fn bench() { // Will be sampled 42 times with 500 iterations per sample. } } mod child3 { #[divan::bench(sample_count = 1)] fn bench() { // Will be sampled 1 time with 500 iterations per sample. } } } ``` -------------------------------- ### Benchmark with Multiple Argument Cases Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Use the `args` option to benchmark a function over different input values. This is useful for comparing performance across various parameters like collection lengths or enum variants. Ensure the argument type implements `Any`, `Copy`, `Send`, `Sync`, and `ToString` (or `Debug`), or use references if `Copy` is not implemented. ```rust #[divan::bench(args = [1000, LEN, len()])] fn init_vec(len: usize) -> Vec { (0..len).collect() } const LEN: usize = // ... fn len() -> usize { // ... } ``` ```rust const LENS: &[usize] = // ... #[divan::bench(args = LENS)] fn bench_vec1(len: usize) -> Vec { // ... } #[divan::bench(args = LENS)] fn bench_vec2(len: usize) -> Vec { // ... } ``` ```rust #[derive(Clone, Copy, Debug)] enum Arg { A, B } #[divan::bench(args = [Arg::A, Arg::B])] fn bench_args(arg: Arg) { // ... } ``` ```rust #[derive(Debug)] enum Arg { A, B } #[divan::bench(args = [Arg::A, Arg::B])] fn bench_args(arg: &Arg) { // ... } ``` ```rust fn strings() -> impl Iterator { // ... } #[divan::bench(args = strings())] fn bench_strings(s: &str) { // ... } ``` ```rust use divan::Bencher; #[divan::bench(args = [1, 2, 3])] fn bench(bencher: Bencher, len: usize) { let value = new_value(len); bencher .counter(len) .bench(|| { do_work(value); }); } ``` -------------------------------- ### Divan API - `Divan` Struct Source: https://docs.rs/divan The `Divan` struct is the benchmark runner. ```APIDOC ## Structs§ Divan The benchmark runner. ``` -------------------------------- ### Implement From for type conversion Source: https://docs.rs/divan/0.1.21/divan/struct.AllocProfiler.html Defines a conversion from one type to another. ```rust fn from(t: T) -> T ``` -------------------------------- ### CharsCount Struct Methods Source: https://docs.rs/divan/0.1.21/divan/counter/struct.CharsCount.html Methods available for creating and initializing a CharsCount instance. ```APIDOC ## pub fn new(count: N) -> Self ### Description Creates a new CharsCount instance by counting N characters. ### Parameters - **count** (N: CountUInt) - Required - The number of characters to count. ## pub fn of_str>(s: &S) -> Self ### Description Creates a new CharsCount instance by counting the characters of a string slice. ### Parameters - **s** (&S) - Required - The string slice to count characters from. ``` -------------------------------- ### Run Benchmarks Across Multiple Threads Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Configures Divan to run benchmarks across multiple threads, useful for measuring contention. A value of 0 uses available parallelism. Equivalent to `--threads` CLI argument or `DIVAN_THREADS` environment variable. ```rust pub fn threads(self, threads: T) -> Self where T: IntoIterator, ``` -------------------------------- ### Bencher::with_inputs Source: https://docs.rs/divan/0.1.21/divan/struct.Bencher.html Generates inputs for the benchmarked function without affecting timing. ```APIDOC ## pub fn with_inputs(self, gen_input: G) -> Bencher<'a, 'b, BencherConfig> ### Description Generate inputs for the benchmarked function. Time spent generating inputs does not affect benchmark timing. ### Parameters - **gen_input** (G) - Required - Closure to generate input data. ### Request Example bencher .with_inputs(|| { String::from("...") }) .bench_values(|s| { s + "123" }); ``` -------------------------------- ### Blanket Implementations Source: https://docs.rs/divan/0.1.21/divan/counter/struct.BytesCount.html Documentation for common Rust blanket implementations applied to generic types within the project. ```APIDOC ## Blanket Implementations ### Description Standard Rust blanket implementations available for all types `T` that satisfy specific trait bounds. ### Methods - **Any**: `type_id(&self) -> TypeId` - Gets the TypeId of self. - **Borrow**: `borrow(&self) -> &T` - Immutably borrows from an owned value. - **BorrowMut**: `borrow_mut(&mut self) -> &mut T` - Mutably borrows from an owned value. - **CloneToUninit**: `unsafe fn clone_to_uninit(&self, dest: *mut u8)` - Performs copy-assignment from self to dest (Nightly). - **From/Into**: Standard type conversion methods. - **ToOwned**: `to_owned(&self) -> T` - Creates owned data from borrowed data. ``` -------------------------------- ### Setting Minimum Benchmark Time Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Control the minimum time a benchmark runs using the `min_time` option. It accepts a `Duration`, seconds as `u64`, or seconds as `f64`. This can be overridden by environment variables or CLI arguments. ```rust use std::time::Duration; #[divan::bench(min_time = Duration::from_secs(3))] fn add() -> i32 { // ... } ``` ```rust #[divan::bench(min_time = 2)] fn int_secs() -> i32 { // ... } ``` ```rust #[divan::bench(min_time = 1.5)] fn float_secs() -> i32 { // ... } ``` -------------------------------- ### Divan API - `AllocProfiler` Struct Source: https://docs.rs/divan The `AllocProfiler` struct measures `GlobalAlloc` memory usage. ```APIDOC ## Structs§ AllocProfiler Measures `GlobalAlloc` memory usage. ``` -------------------------------- ### Benchmarking Equivalent Return/No-Return Cases Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html If the returned value does not need to be dropped, there is no memory cost associated with returning it. Benchmarks returning primitive types like `i32` are equivalent whether they explicitly return the value or use `black_box` on it. ```rust #[divan::bench] fn with_return() -> i32 { let n: i32 = // ... n } #[divan::bench] fn without_return() { let n: i32 = // ... divan::black_box(n); } ``` -------------------------------- ### Counting Inputs as Items with Bencher::count_inputs_as Source: https://docs.rs/divan/0.1.21/divan/struct.Bencher.html Use `Bencher::count_inputs_as` with a `Counter` type like `ItemsCount` to emit metrics based on the input values themselves. This is suitable when inputs are numeric or can be directly converted to a count. ```rust use divan::{Bencher, counter::ItemsCount}; #[divan::bench] fn range_to_vec(bencher: Bencher) { bencher .with_inputs(|| -> usize { // ... }) .count_inputs_as::() .bench_values(|n| -> Vec { (0..n).collect() }); } ``` -------------------------------- ### Benchmarking with Returned Values (Deferred Drop) Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html When a benchmarked function returns a value, its deallocation is deferred until after the sample loop, allowing for precise measurement of construction time only. ```rust use divan::{Bencher, black_box}; #[divan::bench] fn freestanding() -> String { black_box("hello").to_uppercase() } #[divan::bench] fn contextual(bencher: Bencher) { // Setup: let s: String = // ... bencher.bench(|| -> String { black_box(&s).to_lowercase() }); } ``` -------------------------------- ### Generating Inputs for Benchmarking Source: https://docs.rs/divan/0.1.21/divan/struct.Bencher.html Use `Bencher::with_inputs` to provide a closure that generates inputs for the benchmarked function. Time spent generating inputs is not included in benchmark timing. The generated input is passed by value to the `bench_values` closure. ```rust #[divan::bench] fn bench(bencher: divan::Bencher) { bencher .with_inputs(|| { // Generate input: String::from("...") }) .bench_values(|s| { // Use input by-value: s + "123" }); } ``` -------------------------------- ### Divan API - `black_box_drop` Function Source: https://docs.rs/divan The `black_box_drop` function is a convenience function that combines `black_box` and `drop`. ```APIDOC ## Functions§ black_box_drop `black_box` + `drop` convenience function. ``` -------------------------------- ### Benchmark Function with Per-Iteration Generated Inputs (Local, By-Reference) Source: https://docs.rs/divan/0.1.21/divan/struct.Bencher.html Use `bench_local_refs` for benchmarking functions with generated inputs provided by reference, specifically when the benchmark must run in a single thread. This is suitable for functions that are not thread-safe. ```rust #[divan::bench] fn bench(bencher: divan::Bencher) { bencher .with_inputs(|| { // Generate input: String::from("...") }) .bench_local_refs(|s| { // Use input by-reference: *s += "123"; }); } ``` -------------------------------- ### ItemsCount Struct Methods Source: https://docs.rs/divan/0.1.21/divan/counter/struct.ItemsCount.html Methods for creating and managing item counts within the divan crate. ```APIDOC ## ItemsCount ### Description Represents a counter for processing N items. ### Methods - **new(count: N) -> Self** - Creates a new ItemsCount instance for a specific count. - **of_iter(iter: I) -> Self where I: IntoIterator** - Creates a new ItemsCount instance by counting the items in an iterator. ``` -------------------------------- ### Threads Option Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Configure the number of threads for benchmarking to measure contention on atomics and locks. The default is the available parallelism. ```APIDOC ## Threads Option ### Description Benchmarked functions can be run across multiple threads via the `threads` option. This enables you to measure contention on atomics and locks. The default thread count is the available parallelism. ### Usage The `threads` option can be set to any of: * `bool`: `true` for available parallelism, `false` for no parallelism. * `usize`: A specific number of threads. `0` means use available parallelism, and `1` means no parallelism. * `IntoIterator`: For multiple thread counts, such as `Range`, `[usize; N]`, or `&[usize]`. ### Examples ```rust // Use available parallelism #[divan::bench(threads)] fn arc_clone(bencher: divan::Bencher) { let arc = std::sync::Arc::new(42); bencher.bench(|| arc.clone()); } // No parallelism #[divan::bench(threads = false)] fn single() { // ... } // Specific number of threads #[divan::bench(threads = 10)] fn specific() { // ... } // Range of threads #[divan::bench(threads = 0..=8)] fn range() { // Note: Includes 0 for available parallelism. } // Selection of thread counts #[divan::bench(threads = [0, 1, 4, 8, 16])] fn selection() { // ... } ``` ``` -------------------------------- ### Bytes Format Configuration Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Configures how byte counts are scaled in benchmark outputs. This can also be set via the `--bytes-format` CLI argument or `DIVAN_BYTES_FORMAT` environment variable. ```APIDOC ## POST /api/config/bytes-format ### Description Sets the format for displaying byte counts in benchmark results. ### Method POST ### Endpoint /api/config/bytes-format ### Parameters #### Query Parameters - **format** (BytesFormat) - Required - The desired format for byte scaling (e.g., "auto", "si", "iec"). ### Request Example ```json { "format": "si" } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message indicating the format has been updated. #### Response Example ```json { "message": "Bytes format set to SI." } ``` ``` -------------------------------- ### Divan Throughput API Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Methods for tracking throughput metrics during benchmarks. ```APIDOC ## Throughput Methods ### Description Methods to track items or bytes processed during benchmarks. ### Throughput Options - **counter(counter: IntoCounter)**: Adds a custom counter. - **items_count(count: Into)**: Sets the number of items processed. - **bytes_count(count: Into)**: Sets the number of bytes processed. ``` -------------------------------- ### Compile Error: Applying `#[divan::bench]` Multiple Times Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Applying the `#[divan::bench]` attribute more than once to the same item will result in a compile-time error. ```rust #[divan::bench] #[divan::bench] fn bench() { // ... } ``` -------------------------------- ### Benchmarking with Multiple Threads Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Use the `threads` option to run benchmarks across multiple threads. The default is available parallelism. It accepts a boolean, a specific `usize` count, or an iterator over `usize` values. ```rust use std::sync::Arc; #[divan::bench(threads)] fn arc_clone(bencher: divan::Bencher) { let arc = Arc::new(42); bencher.bench(|| arc.clone()); } ``` ```rust #[divan::bench(threads = false)] fn single() { // ... } ``` ```rust #[divan::bench(threads = 10)] fn specific() { // ... } ``` ```rust #[divan::bench(threads = 0..=8)] fn range() { // Note: Includes 0 for available parallelism. } ``` ```rust #[divan::bench(threads = [0, 1, 4, 8, 16])] fn selection() { // ... } ``` -------------------------------- ### Benchmark Function with Per-Iteration Generated Inputs (By-Reference) Source: https://docs.rs/divan/0.1.21/divan/struct.Bencher.html Use `bench_refs` to benchmark a function that accepts generated inputs by reference. The input is regenerated for each iteration and can be used in parallel benchmarks. ```rust #[divan::bench] fn bench(bencher: divan::Bencher) { bencher .with_inputs(|| { // Generate input: String::from("...") }) .bench_refs(|s| { // Use input by-reference: *s += "123"; }); } ``` -------------------------------- ### Minimum Time Option Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Set the minimum duration for each benchmark iteration using `min_time`. This can be overridden at runtime. ```APIDOC ## Minimum Time Option (`min_time`) ### Description The minimum time spent benchmarking each function can be set to a predetermined `Duration` via the `min_time` option. This may be overridden at runtime using either the `DIVAN_MIN_TIME` environment variable or `--min-time` CLI argument. Unless `skip_ext_time` is set, this includes time external to the benchmarked function, such as time spent generating inputs and running `Drop`. ### Usage Can be set to a `std::time::Duration` or a numeric value representing seconds (`u64` or `f64`). Invalid numeric values will cause a panic at runtime. ### Examples ```rust use std::time::Duration; #[divan::bench(min_time = Duration::from_secs(3))] fn add() -> i32 { // ... } #[divan::bench(min_time = 2)] // 2 seconds as u64 fn int_secs() -> i32 { // ... } #[divan::bench(min_time = 1.5)] // 1.5 seconds as f64 fn float_secs() -> i32 { // ... } ``` ``` -------------------------------- ### bench_refs Source: https://docs.rs/divan/0.1.21/divan/struct.Bencher.html Benchmarks a function over per-iteration generated inputs provided by-reference. Supports parallel execution. ```APIDOC ## bench_refs ### Description Benchmarks a function over per-iteration generated inputs, provided by-reference. The function is called exactly once for each generated input and can be executed in parallel. ### Parameters - **benched** (Fn(&mut I) -> O + Sync) - Required - The function to benchmark. ### Request Example ```rust bencher.with_inputs(|| String::from("...")).bench_refs(|s| *s += "123"); ``` ``` -------------------------------- ### TryInto Trait Methods Source: https://docs.rs/divan/0.1.21/divan/counter/struct.ItemsCount.html Documentation for the TryInto trait methods used for fallible type conversion. ```APIDOC ## fn try_into(self) -> Result>::Error> ### Description Performs the conversion from type T to type U. This is a fallible conversion that returns a Result. ### Parameters - **self** (T) - Required - The instance to be converted. ### Response - **Result** - Returns Ok(U) if the conversion succeeds, or an Error if it fails. ``` -------------------------------- ### Implement TryFrom for fallible conversion Source: https://docs.rs/divan/0.1.21/divan/struct.AllocProfiler.html Performs a conversion that may fail, returning a Result. ```rust type Error = Infallible fn try_from(value: U) -> Result>::Error> ``` -------------------------------- ### Configure a single counter for a benchmark group Source: https://docs.rs/divan/0.1.21/divan/attr.bench_group.html Use the singular counter attribute for simpler tracking of a single metric. ```rust use divan::counter::BytesCount; const STR: &str = "..."; #[divan::bench_group(counter = BytesCount::of_str(STR))] mod chars { use super::STR; #[divan::bench] fn count() -> usize { divan::black_box(STR).chars().count() } #[divan::bench] fn collect() -> String { divan::black_box(STR).chars().collect() } } ``` -------------------------------- ### Set Minimum Benchmark Time Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Sets the minimum duration a benchmark function should run. Equivalent to the `--min-time` CLI argument. ```rust pub fn min_time(self, time: Duration) -> Self ``` -------------------------------- ### Implement TryInto for fallible conversion Source: https://docs.rs/divan/0.1.21/divan/struct.AllocProfiler.html Performs a fallible conversion into a target type. ```rust type Error = >::Error fn try_into(self) -> Result>::Error> ``` -------------------------------- ### Set Output Coloring Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Configures whether the benchmark output should use colors. Accepts a boolean or an Option, where None defaults to auto-detection. ```rust pub fn color(self, yes: impl Into>) -> Self ``` -------------------------------- ### Ignore Benchmark within `#[divan::bench]` Attribute Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Alternatively, the `ignore` option can be set directly within the `#[divan::bench]` attribute for a more concise syntax. ```rust #[divan::bench(ignore)] fn todo() { unimplemented!(); } ``` -------------------------------- ### Register a benchmarking group Source: https://docs.rs/divan/0.1.21/divan/attr.bench_group.html Basic usage of the bench_group attribute macro. ```rust #[bench_group] ``` -------------------------------- ### Bencher::input_counter Source: https://docs.rs/divan/0.1.21/divan/struct.Bencher.html Creates a counter for each input of the benchmarked function. ```APIDOC ## pub fn input_counter(self, make_counter: F) -> Self ### Description Calls a closure to create a Counter for each input of the benchmarked function. ### Parameters - **make_counter** (Fn(&I) -> C + Sync + 'static) - Required - Closure to create a counter from input. ### Request Example bencher .with_inputs(|| -> String { ... }) .input_counter(BytesCount::of_str) .bench_refs(|s| { s.chars().count() }); ``` -------------------------------- ### Set Sample Size Source: https://docs.rs/divan/0.1.21/divan/struct.Divan.html Configures the number of iterations within a single sample for each benchmark. Equivalent to the `--sample-size` CLI argument. ```rust pub fn sample_size(self, count: u32) -> Self ``` -------------------------------- ### Benchmarking a lazy Iterator with for_each Source: https://docs.rs/divan/0.1.21/divan/fn.black_box_drop.html Use this when benchmarking a lazy Iterator to completion with for_each. It requires the divan crate. ```rust #[divan::bench] fn parse_iter() { let input: &str = // ... Parser::new(input) .for_each(divan::black_box_drop); } ``` -------------------------------- ### Implement Into for type conversion Source: https://docs.rs/divan/0.1.21/divan/struct.AllocProfiler.html Performs a conversion by calling the corresponding From implementation. ```rust fn into(self) -> U ``` -------------------------------- ### Emitting Performance Counters Source: https://docs.rs/divan/0.1.21/divan/attr.bench.html Configure performance counters using the `counters` option to emit metrics like bytes or items processed. `BytesCount::of_slice` and `ItemsCount::new` are used here. For a single counter, use the `counter` option. ```rust use divan::{Bencher, counter::{BytesCount, ItemsCount}}; const INTS: &[i32] = &[ // ... ]; #[divan::bench(counters = [ BytesCount::of_slice(INTS), ItemsCount::new(INTS.len()), ])] fn sort(bencher: Bencher) { bencher .with_inputs(|| INTS.to_vec()) .bench_refs(|ints| ints.sort()); } ``` ```rust use divan::counter::BytesCount; const STR: &str = "..."; #[divan::bench(counter = BytesCount::of_str(STR))] fn char_count() -> usize { divan::black_box(STR).chars().count() } ```