Struct divan::Bencher

source ·
pub struct Bencher<'a, 'b, C = BencherConfig> { /* private fields */ }
Expand description

Enables contextual benchmarking in #[divan::bench].

Examples

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::<Vec<i32>>();
    let mut dst = vec![0; src.len()];

    bencher.bench_local(|| {
        black_box(&mut dst).copy_from_slice(black_box(&src));
    });
}

Implementations§

source§

impl<'a, 'b> Bencher<'a, 'b>

source

pub fn bench<O, B>(self, benched: B)
where B: Fn() -> O + Sync,

Benchmarks a function.

The function can be benchmarked in parallel using the threads option. If the function is strictly single-threaded, use Bencher::bench_local instead.

Examples
#[divan::bench]
fn bench(bencher: divan::Bencher) {
    bencher.bench(|| {
        // Benchmarked code...
    });
}
source

pub fn bench_local<O, B>(self, benched: B)
where B: FnMut() -> O,

Benchmarks a function on the current thread.

Examples
#[divan::bench]
fn bench(bencher: divan::Bencher) {
    bencher.bench_local(|| {
        // Benchmarked code...
    });
}
source

pub fn with_inputs<G>(self, gen_input: G) -> Bencher<'a, 'b, BencherConfig<G>>

Generate inputs for the benchmarked function.

Time spent generating inputs does not affect benchmark timing.

When benchmarking in parallel, the input generator is called on the same thread as the sample loop that uses that input.

Examples
#[divan::bench]
fn bench(bencher: divan::Bencher) {
    bencher
        .with_inputs(|| {
            // Generate input:
            String::from("...")
        })
        .bench_values(|s| {
            // Use input by-value:
            s + "123"
        });
}
source§

impl<'a, 'b, GenI> Bencher<'a, 'b, BencherConfig<GenI>>

source

pub fn counter<C>(self, counter: C) -> Self
where C: IntoCounter,

Assign a Counter for all iterations of the benchmarked function.

This will either:

  • Assign a new counter
  • Override an existing counter of the same type

If the counter depends on generated inputs, use Bencher::input_counter instead.

If context is not needed, the counter can instead be set via #[divan::bench(counters = ...)].

Examples
use divan::{Bencher, counter::BytesCount};

#[divan::bench]
fn char_count(bencher: Bencher) {
    let s: String = // ...

    bencher
        .counter(BytesCount::of_str(&s))
        .bench(|| {
            divan::black_box(&s).chars().count()
        });
}
source§

impl<'a, 'b, I, GenI> Bencher<'a, 'b, BencherConfig<GenI>>
where GenI: FnMut() -> I,

Benchmark over generated inputs.

source

pub fn input_counter<C, F>(self, make_counter: F) -> Self
where F: Fn(&I) -> C + Sync + 'static, C: IntoCounter,

Create a Counter for each input of the benchmarked function.

This will either:

  • Assign a new counter
  • Override an existing counter of the same type

If the counter is constant, use Bencher::counter instead.

When benchmarking in parallel, the input counter is called on the same thread as the sample loop that generates and uses that input.

Examples

The following example emits info for the number of bytes processed when benchmarking char-counting. The byte count is gotten by calling BytesCount::of_str on each iteration’s input String.

use divan::{Bencher, counter::BytesCount};

#[divan::bench]
fn char_count(bencher: Bencher) {
    bencher
        .with_inputs(|| -> String {
            // ...
        })
        .input_counter(BytesCount::of_str)
        .bench_refs(|s| {
            s.chars().count()
        });
}
source

pub fn bench_values<O, B>(self, benched: B)
where B: Fn(I) -> O + Sync, GenI: Fn() -> I + Sync,

Benchmarks a function over per-iteration generated inputs, provided by-value.

Per-iteration means the benchmarked function is called exactly once for each generated input.

The function can be benchmarked in parallel using the threads option. If the function is strictly single-threaded, use Bencher::bench_local_values instead.

Examples
#[divan::bench]
fn bench(bencher: divan::Bencher) {
    bencher
        .with_inputs(|| {
            // Generate input:
            String::from("...")
        })
        .bench_values(|s| {
            // Use input by-value:
            s + "123"
        });
}
source

pub fn bench_local_values<O, B>(self, benched: B)
where B: FnMut(I) -> O,

Benchmarks a function over per-iteration generated inputs, provided by-value.

Per-iteration means the benchmarked function is called exactly once for each generated input.

Examples
#[divan::bench]
fn bench(bencher: divan::Bencher) {
    let mut values = Vec::new();
    bencher
        .with_inputs(|| {
            // Generate input:
            String::from("...")
        })
        .bench_local_values(|s| {
            // Use input by-value:
            values.push(s);
        });
}
source

pub fn bench_refs<O, B>(self, benched: B)
where B: Fn(&mut I) -> O + Sync, GenI: Fn() -> I + Sync,

Benchmarks a function over per-iteration generated inputs, provided by-reference.

Per-iteration means the benchmarked function is called exactly once for each generated input.

Examples
#[divan::bench]
fn bench(bencher: divan::Bencher) {
    bencher
        .with_inputs(|| {
            // Generate input:
            String::from("...")
        })
        .bench_refs(|s| {
            // Use input by-reference:
            *s += "123";
        });
}
source

pub fn bench_local_refs<O, B>(self, benched: B)
where B: FnMut(&mut I) -> O,

Benchmarks a function over per-iteration generated inputs, provided by-reference.

Per-iteration means the benchmarked function is called exactly once for each generated input.

Examples
#[divan::bench]
fn bench(bencher: divan::Bencher) {
    bencher
        .with_inputs(|| {
            // Generate input:
            String::from("...")
        })
        .bench_local_refs(|s| {
            // Use input by-reference:
            *s += "123";
        });
}

Trait Implementations§

source§

impl<C> Debug for Bencher<'_, '_, C>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, 'b, C = BencherConfig> !RefUnwindSafe for Bencher<'a, 'b, C>

§

impl<'a, 'b, C = BencherConfig> !Send for Bencher<'a, 'b, C>

§

impl<'a, 'b, C> Sync for Bencher<'a, 'b, C>
where C: Sync,

§

impl<'a, 'b, C> Unpin for Bencher<'a, 'b, C>
where C: Unpin,

§

impl<'a, 'b, C = BencherConfig> !UnwindSafe for Bencher<'a, 'b, C>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.